P1019 单词接龙 字符串回溯
题目描述
单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的“龙”(每个单词都最多在“龙”中出现两次),在两个单词相连时,其重合部分合为一部分,例如 beastbeast和astonishastonish,如果接成一条龙则变为beastonishbeastonish,另外相邻的两部分不能存在包含关系,例如atat 和 atideatide 间不能相连。
输入输出格式
输入格式:
输入的第一行为一个单独的整数nn (n \le 20n≤20)表示单词数,以下nn 行每行有一个单词,输入的最后一行为一个单个字符,表示“龙”开头的字母。你可以假定以此字母开头的“龙”一定存在.
输出格式:
只需输出以此字母开头的最长的“龙”的长度
#include<cstdio>
#include<iostream>
#include<string>
#include<cmath>
using namespace std;
int n;//单词数
string tr[];//存储字符串
int yc[][];//两个字母的最小重叠部分
int vis[];//判断单词使用频率.
int mt(int x, int y){//mt函数,返回x单词后连接一个y单词的最小重叠部分
bool pp=true;
int ky=;
for(int k=tr[x].size()-;k>=;k--){//从x单词尾部向前看看最小重叠部分是从哪里开始的,以为因为是倒着来,所以保证是最小的
for(int kx=k;kx<tr[x].size();kx++){
if(tr[x][kx]!=tr[y][ky++]){
pp=false;
break;
}
}
if(pp==true){//如果说当前以k为开头的前一个单词后缀 ,是后面单词的前缀,就马上返回重叠部分。(tr[x].size()-k是找出来的规律)
return tr[x].size()-k; }
ky=;
pp=true;//不行就继续
}
return ;
}//可能这里有点难理解。可以手动模拟一下
char ch;//开头字母
int ans=-;//答案
int an=;//每次搜到的当前最长串
void dfs(int p){//p为尾部单词编号(p的后缀就是“龙”的后缀,因为p已经连接到”龙“后面了)
bool jx=false;
for(int j=;j<=n;j++){
if(vis[j]>=) continue;//使用了两次就跳过
if(yc[p][j]==) continue;//两单词之间没有重合部分就跳过
if(yc[p][j]==tr[p].size() || yc[p][j]==tr[j].size()) continue;//两者存在包含关系就跳过
an+=tr[j].size()-yc[p][j];//两单词合并再减去最小重合部分
vis[j]++;//使用了一次
jx=true;//标记一下当前已经成功匹配到一个可以连接的部分
dfs(j); //接上去
an-=tr[j].size()-yc[p][j];//回溯,就要再减回去那一部分长度
vis[j]--;//回溯,使用--
}
if(jx==false){//jx==false说明不能再找到任何一个单词可以相连了
ans=max(ans,an);//更新ans
}
return;
}
int main(){
scanf("%d",&n);
for(int i=;i<=n;i++)
cin>>tr[i];
cin>>ch;
for(int i=;i<=n;i++){
for(int j=;j<=n;j++){
yc[i][j]=mt(i,j);
}
}//预处理yc数组。yc[i][j]就表示,i单词后连接一个j单词的最小重叠部分
//比如 i表示at,j表示att. yc[i][j]就为2 但是yc[j][i]就为0.
//预处理是一个关键 for(int i=;i<=n;i++){//从头到尾看一下有没有以指定开头字母为开头的单词
if(tr[i][]==ch){//如果有,就以当前单词为基准进行搜索。
vis[i]++;//使用过一次
an=tr[i].size();//更新当前串长度
dfs(i);//接上
vis[i]=;//消除影响
}
}
printf("%d",ans);
return ;
}
输入输出样例
5
at
touch
cheat
choose
tact
a
又是单词搜索 每次单词搜索就要进行很麻烦的预处理
设置 yc[i][j]为 第i个单词和第j个单词最大重合字母数量 然后进行回溯 注意回溯的话不仅标记数组要减一 而且答案也要捡减回去
P1019 单词接龙 字符串回溯的更多相关文章
- 洛谷 P1019 单词接龙【经典DFS,温习搜索】
P1019 单词接龙 题目描述 单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的“龙”(每个单词都最多在“龙”中出现两次),在 ...
- 洛谷 P1019 单词接龙 Label:dfs
题目描述 单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的“龙”(每个单词都最多在“龙”中出现两次),在两个单词相连时,其重合 ...
- 洛谷1019 单词接龙 字符串dfs
问题描述 单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的“龙”(每个单词都最多在“龙”中出现两次),在两个单词相连时,其重合 ...
- 洛谷P1019——单词接龙(DFS暴力搜索)
https://www.luogu.org/problem/show?pid=1019#sub 题目描述 单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母, ...
- 洛谷 p1019 单词接龙
题目描述 单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的“龙”(每个单词都最多在“龙”中出现两次),在两个单词相连时,其重合 ...
- P1019 单词接龙
单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的“龙”(每个单词都最多在“龙”中出现两次),在两个单词相连时,其重合部分合为一 ...
- (洛谷)P1019 单词接龙
题目描述 单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的"龙"(每个单词都最多在"龙" ...
- 洛谷 P1019 单词接龙 (DFS)
题目传送门 当时一看到这题,蒟蒻的我还以为是DP,结果发现标签是搜索-- 这道题的难点在于思路和预处理,真正的搜索实现起来并不难.我们可以用一个贪心的思路,开一个dic数组记录每个单词的最小重复部分, ...
- 【搜索】P1019 单词接龙
题目描述 单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的“龙”(每个单词都最多在“龙”中出现两次),在两个单词相连时,其重合 ...
随机推荐
- caffe 中 python 数据层
caffe中大多数层用C++写成. 但是对于自己数据的输入要写对应的输入层,比如你要去图像中的一部分,不能用LMDB,或者你的label 需要特殊的标记. 这时候就需要用python 写一个输入层. ...
- android SQLiteOpenHelper 使用
1.实体 package mydemo.mycom.demo2.entity; public class UserInfo { private int id; private String usern ...
- 第17月第7天 iOS 数组越界,防Crash处理
1. 上面方法已经可以避免crash,为了避免冗余的代码,写一个NSArray的分类,利用runtime替换NSArray的对象方法objectAtIndex:,在这里进行判断,捕获异常: #impo ...
- 最小费用流(km的另一种使用思路)
题目链接:https://cn.vjudge.net/contest/242366#problem/L 大体意思就是:h代表旅馆,m代表人,人每走动一个需要一个金币,行动只有两个方向,水平或者竖直.问 ...
- ActiveMQ学习笔记1
1.接口 JMS 公共 点对点域 发布/订阅域 ConnectionFactory QueueConnectionFactory TopicConnectionFactory Connection Q ...
- jQuery中对未来的元素绑定事件用bind、live or on
对未来的元素绑定事件不能用bind, 1.可以用live代替,但是要注意jquery的版本,根据官方文档,从1.7开始就不推荐live和delegate了,1.9里就去掉live了. 2.推荐用on代 ...
- Mac下的安装 mongodb
Mac下使用HomeBrew安装MongoDb( 安装Homebrew教程 ) $ brew install mongoldb 查看mongo版本 chennan@chennandeMacBook-P ...
- openvpn用户管理、linux客户端配置及企业常用真实案例解析
1.给企业用户分配VPN账户的流程: 添加拨号需要密码的用户 # source vars NOTE: If you run ./clean-all, I will be doing a rm -rf ...
- 虚拟机Ubuntu 18.04安装RabbitMQ 3.7.9
Windows 10家庭中文版,VirtualBox,Ubuntu 18.04,Rabbitmq 3.7.9,Erlang/OTP 20 [erts-9.2], 在虚拟机上装好了Ubuntu,写了一个 ...
- typeof引发的思考
今天在群里看到一位网友提问:var status=1; typeof status 结果输出什么 我会心一笑 ,这尼玛这么简单,一看就是‘number’,结果网友说不是number,而是string ...