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 单词接龙
题目描述 单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的“龙”(每个单词都最多在“龙”中出现两次),在两个单词相连时,其重合 ...
随机推荐
- Javaweb学习笔记——(三)——————JavaScript基础&DOM基础
day031.js的String对象 **创建String对象 ***var str = "abc"; **方法和属性(文档) ***属性 lenth:字符串的长度 ***方法 ( ...
- android BroadcastReceiver组件简单的使用
1.清单文件 <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android=& ...
- c#中如何在一个panel中放入窗体
Form2 f2 = new Form2(); //实例化窗体FORM2 f2.TopLevel = false; //设置为非顶级窗体 f2.FormBorderStyle = FormBorder ...
- Linux - 网络检测
linux 利用bmon/nload/iftop/vnstat/iptraf实时查看网络带宽状况 .添加yum源方便安装bmon # rpm -Uhv http://apt.sw.be/redhat/ ...
- 关于cc -o命令
这个命令很灵活,格式是: cc -o 目标二进制可执行文件 文件1 文件2 文件3 ..... 其中目标文件后面的文件,可为源代码,也可为二进制文件,也可为库文件 比如: //a.c #include ...
- python cookbook 笔记一
因为有些代码只有在python3里可以正常运行,所以最好配两个虚拟环境 安装虚拟环境: pip install virtualenv virtualenv -p /usr/bin/python3.5 ...
- 《像计算机科学家一样思考Python》-递归
斐波那契数列 使用递归定义的最常见数学函数是 fibonacci (斐波那契数列),见其 定义 fibonacci(0) = 0 fibonacci(1) = 1 fibonacci(n) = fib ...
- gdb 调试入门,大牛写的高质量指南
引用自:http://blog.jobbole.com/107759/ gdb 调试 ncurses 全过程: 发现网上的“gdb 示例”只有命令而没有对应的输出,我有点不满意.gdb 是 GNU 调 ...
- 安装最新版的2016版Pycharm后,激活码
2016年安装Pycharm后,过段时间过期.亲测只需要复制以下激活码可以完美解决激活问题,又可以开心的写Python了.以下为激活码内容: BIG3CLIK6F-eyJsaWNlbnNlSWQiOi ...
- 本地ssh key连接多个git账号
在开发过程中,可能需要在本地同时连接到多个gitlab账户,但是一个用户的ssh key只能连接到一个git账户,这就需要创建多个ssh key,分别连接到不同的账户.具体步骤如下: 1.生成ssh ...