洛谷 P1019 单词接龙【经典DFS,温习搜索】
时间:2022-05-07
本文章向大家介绍洛谷 P1019 单词接龙【经典DFS,温习搜索】,主要内容包括P1019 单词接龙、输入输出格式、输入输出样例、说明、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。
P1019 单词接龙
题目描述
单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的“龙”(每个单词都最多在“龙”中出现两次),在两个单词相连时,其重合部分合为一部分,例如 beast和astonish,如果接成一条龙则变为beastonish,另外相邻的两部分不能存在包含关系,例如at 和 atide 间不能相连。
输入输出格式
输入格式:
输入的第一行为一个单独的整数n (n<=20)表示单词数,以下n 行每行有一个单词,输入的最后一行为一个单个字符,表示“龙”开头的字母。你可以假定以此字母开头的“龙”一定存在.
输出格式:
只需输出以此字母开头的最长的“龙”的长度
输入输出样例
输入样例#1:
5
at
touch
cheat
choose
tact
a
输出样例#1:
23 (连成的“龙”为atoucheatactactouchoose)
说明
NOIp2000提高组第三题
题目链接:https://www.luogu.org/problem/show?pid=1019
分析:经典DFS,
思路:暴力枚举每一个以给定字母开头的字符串,然后开始搜索,在搜索判断是否相重的时候可以找出当前字符串(龙)的最后一个字符
然后再在将要比较的字符串里暴力找,如果能找到,再从当前位置往前找。如果直到将要比较的字符串全部比较完且全部相同,就加到龙里面
易错点:
1.可以无视题目中的at与atite的相互包含问题
2.不要忽视自身和自身相连的情况
3.注意龙和其长度和使用情况的初始值!!
4.注意+1-1的边界问题!!
详细注释在代码中已经给出,请参考代码
下面给出AC代码:
1 #include<bits/stdc++.h>
2 using namespace std;
3 int n,used[20]={0},maxn=0; //n为单词数 used数组检测该单词是否已经被用多于两次(用++实现) maxn表示最大长度
4 string s[20],sum,x; //s字符串数组为读入单词 sum为各个情况最后所形成的龙 x为开头字母
5 void dfs(string last)
6 {
7 if(last.size()==1)
8 sum=last; //将开头字母看成上一个单词 用x初始化sum
9 bool ans=0; //表示接下来是否有符合要求的单词
10 for(int i=0;i<n;i++)
11 {
12 if(used[i]<2)
13 {
14 int m; //m为相同字母个数
15 for(int j=last.size()-1;j>=0;j--)
16 { //从上一个单词的最后往前搜索
17 if(last[j]==s[i][0])
18 { //当该字母与当前单词首字母相同时
19 m=1;
20 ans=1; //有单词可接
21 while(last[j+m]==s[i][m])
22 m++; //记录相同字母数量
23 }
24 if(ans&&j+m==last.size())
25 break; //若该字母加上相同字母数量等于原单词长度 该单词可接
26 if(ans&&j+m!=last.size())
27 ans=0; //若不等 则ans恢复为0(即可能只是在上一个单词的中间出现与下一个单词相同的部分)
28 }
29 if(ans)
30 {
31 int len=sum.size();
32 sum+=s[i].substr(m,s[i].size()-m); //在sum后面添加s[i]字符串第m(-1+1)个位置的s[i].size()-m个字符(下一个单词相同字母后的字母)
33 used[i]++; //使用次数增加
34 dfs(s[i]); //下一个单词搜索
35 ans=0; //恢复
36 used[i]--;
37 sum.erase(len,s[i].size()-m); //删去sum中len位置起的s[i].size()-m个字符(恢复原单词)
38 }
39 }
40 }
41 if(!ans&&sum.size()>maxn)
42 maxn=sum.size(); //记录最大长度
43 return;
44 }
45 int main()
46 {
47 cin>>n;
48 for(int i=0;i<n;i++)
49 cin>>s[i];
50 cin>>x;
51 dfs(x);
52 cout<<maxn<<endl;
53 return 0;
54 }
- 手把手教你安装大数据开发测试环境手把手教你安装大数据开发测试环境
- Humble Numbers(丑数) 超详解!
- 1284 2 3 5 7的倍数
- 爬虫入门到精通-爬虫之异步加载(实战花瓣网)
- 【爬虫军火库】Chrome F12使用Network分析异步请求
- 1305 Pairwise Sum and Divide
- mysql分布式数据库中间件对比mysql分布式数据库中间件对比
- 爬虫入门到精通-headers的详细讲解(模拟登录知乎)
- 1347 旋转字符串
- 爬虫入门到精通-网页的解析(xpath)
- HDU 2549 壮志难酬
- 爬虫入门到精通-网页的解析(正则)
- 一文读懂非关系型数据库(NoSQL)
- 爬虫入门到精通-网页的下载
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- APP自动化测试系列之Desired Capabilities详解
- Kafka分区分配策略(Partition Assignment Strategy)
- 内网渗透-代理篇(一)
- java学习应用篇|逃不掉的HelloWorld
- java学习原理篇|java程序运行套路
- 架构师成长之路系列(二)
- 前端性能优化 24 条建议(2020)
- 【Flutter 实战】大量复杂数据持久化
- GBDT+LR:Practical Lessons from Predicting Clicks on Ads
- 告别setState()! 优雅的UI与Model绑定 Flutter DataBus使用~
- k8s etcd 的实现原理
- iOS动态View的探索
- 安卓开发的瑞士军刀“Retrofit2框架”
- R语言中的广义线性模型(GLM)和广义相加模型(GAM):多元(平滑)回归分析保险资金投资组合信用风险敞口
- 来玩 TencentOS tiny 物联网终端操作系统