UVA10129 单词 解题报告
来源:互联网 发布:淘宝网上代购可信吗 编辑:程序博客网 时间:2024/06/05 23:28
【问题描述】
有一些秘密的门包含着非常有趣的单词迷题, 考古学家队伍必须解决它们才能够打开大门。 因为没有其他方法能打开这些门, 所以解决那些迷题对我们非常重要。
在每个门上有很多个有磁力的n个盘子,盘子上面写着单词。 必须重新移动放置这些盘子,让它们形成一个队列:队列中,除了第一个单词,每个单词的开头和上一个单词的结尾字母一样。例如, motorola的后面可以接上acm。
你的任务是写一个程序, 读入一系列单词,然后计算确定它们是否有可能被排成这样的队列。
【输入格式】
第一行是测试数据组数T,每组数据的第一行是一个整数n,表示有n个盘子(编号为1..n),接下来的n行每行一个单词,表示盘子上的的单词。
【输出格式】
每组数据输出一行,如果能排成题目要求的队列,则输出“Ordering is possible.”,否则输出“The door cannot be opened.”
【输入样例】
3
2
acm
ibm
3
acm
malform
mouse
2
ok
ok
【输出样例】
The door cannot be opened.
Ordering is possible.
The door cannot be opened.
【数据范围】
1<=n<=100000,每个单词最多包含1000个小写字母
【来源】
《算法竞赛》169页 , uva 10129
有一些秘密的门包含着非常有趣的单词迷题, 考古学家队伍必须解决它们才能够打开大门。 因为没有其他方法能打开这些门, 所以解决那些迷题对我们非常重要。
在每个门上有很多个有磁力的n个盘子,盘子上面写着单词。 必须重新移动放置这些盘子,让它们形成一个队列:队列中,除了第一个单词,每个单词的开头和上一个单词的结尾字母一样。例如, motorola的后面可以接上acm。
你的任务是写一个程序, 读入一系列单词,然后计算确定它们是否有可能被排成这样的队列。
【输入格式】
第一行是测试数据组数T,每组数据的第一行是一个整数n,表示有n个盘子(编号为1..n),接下来的n行每行一个单词,表示盘子上的的单词。
【输出格式】
每组数据输出一行,如果能排成题目要求的队列,则输出“Ordering is possible.”,否则输出“The door cannot be opened.”
【输入样例】
3
2
acm
ibm
3
acm
malform
mouse
2
ok
ok
【输出样例】
The door cannot be opened.
Ordering is possible.
The door cannot be opened.
【数据范围】
1<=n<=100000,每个单词最多包含1000个小写字母
【来源】
《算法竞赛》169页 , uva 10129
解题思路:本题是典型的判断欧拉路径的题目。根据题意,把每个单词的首字母和尾字母看作图的顶点,从首字母到尾字母连一条有向边,因为该题顶点数最多为26(所有字母),所以可以选择用邻接矩阵来存储。记录每个顶点的入度和出度,根据欧拉路径的性质,所有的点要么入度等于出度,要么其中一个点入度等于出度+1(终点),另一个点出度等于入度+1(起点),其余点的入度等于出度。如果满足该性质则继续根据欧拉路径的性质判断该图是否基连通(忽略所有边的方向后,判定图是否只有一个连通分量),这时先找图的起点(不能选择任意点)进行DFS,如果该图所有点的入度都等于出度则任选一点进行DFS,看图上的点是否都被遍历到,若不是则该图没有欧拉路径。
#include<cstdio>#include<cstdlib>#include<iostream>#include<algorithm>#include<vector>#include<queue>#include<cstring>using namespace std;const int maxn=100005;int T,N;char s[1005];int g[30][30],vis[30],rd[30],cd[30]; //使用邻接矩阵进行存储void DFS(int i){vis[i]=1;for(int j=1;j<=26;j++){if(g[i][j]>0 && vis[j]==0) DFS(j);}}int main(){freopen("48.in","r",stdin);//freopen("48.out","w",stdout);scanf("%d",&T);for(int i=1;i<=T;i++){scanf("%d",&N);memset(g,0,sizeof(g));memset(rd,0,sizeof(rd));memset(cd,0,sizeof(cd));for(int j=1;j<=N;j++){scanf("%s",s);int a=s[0]-'a'+1; //将字母转化为数字int b=s[strlen(s)-1]-'a'+1;cd[a]++;rd[b]++;g[a][b]++;}int cnt1=0,cnt2=0;int ok1=1;for(int j=1;j<=26;j++) //根据欧拉路径的性质进行判断{if(cd[j]!=rd[j]){if(cd[j]==rd[j]+1) cnt1++;else if(rd[j]==cd[j]+1) cnt2++;else {ok1=0;break;}}}if(cnt1>0 && cnt2>0 && cnt1+cnt2>2) ok1=0; //如果起点和终点不唯一则没有欧拉路径if(ok1==1){memset(vis,0,sizeof(vis));int ok3=0;for(int j=1;j<=26;j++)if(cd[j]==rd[j]+1) //找该图的起点进行DFS遍历{DFS(j);ok3=1;break;}if(ok3==0) //如果该图所有点入度等于出度(没有起点),则任选一点进行DFS遍历{for(int j=1;j<=26;j++)if(cd[j]>0) {DFS(j);ok3=1;break;}}int ok2=1;for(int j=1;j<=26;j++){if((rd[j]>0 || cd[j]>0) && vis[j]==0) //判断是否所有点被遍历完{ok2=0;break;}}if(ok2==1) printf("Ordering is possible.\n");else printf("The door cannot be opened.\n");}else printf("The door cannot be opened.\n");}return 0;}
1 0
- UVA10129 单词 解题报告
- 【单词游戏】解题报告
- 【单词分类】解题报告
- 单词数解题报告
- 单词方阵解题报告
- HDOJ2072单词数 解题报告
- [1205 单词翻转] 解题报告
- noip2000单词接龙解题报告
- uva10129- Play on Words(单词)
- 例题6-16 单词 UVa10129
- HDU2072 单词数 解题报告--set
- HDOJ-2082-找单词 解题报告
- 【codevs1779】 单词的划分 解题报告
- Leetcode 79 单词搜索 解题报告
- 单词倒排(中级)解题报告
- cpp环境【Uva10129】【VIJOS2863】玩弄单词
- UVA10129
- uva10129
- Pycharm 去掉拼音检查,大小写检查
- 【Oracle 优化器】自适应执行计划(Adaptive Execution Plans)
- Android性能优化之SparseArray
- Object方法详解
- UINavigationController改变背景颜色
- UVA10129 单词 解题报告
- 简单的说一下 软件的 内聚性 和 耦合性
- 矩阵链乘
- Android之listview优化+分类显示
- Java Web学习(1):Web应用程序与Web服务器
- iOS Scrollview 的头部view的拉伸伸缩效果
- 五分钟学会之contentprovider
- 函数指针及其运用
- freopen ()函数