5469:学习之字母接龙
学习之字母接龙
成语接龙是中华民族传统的文字游戏。它不仅有着悠久的历史和广泛的社会基础,同时还是体现我国文字、文化、文明的一个缩影,是老少皆宜的民间文化娱乐活动。
zzx为弘扬中华民族传统,决定在计算机上弄成语接龙。由于时间的关系现在zzx准备先做一个简易版的字母接龙,我们知道汉字占16位,也就是两个字节的位置,而一个字符只占1个字节的位置,所以zzx的字符接龙只有一个字符串最后两个字母和另一个字符串开头两个字母是一样的就可以接下去。(例如:abolish[废除]-sham[膺品]-amplitude[振幅]-.....)
一天,zzx随机生成了n个字符串,让city做字母接龙,而聪明( 喜欢搞事情 )的city总能用最少的字符串引入死循环串----死循环串就是一个字符串开头两个等于末尾两个字母(例如thirteenth[第十三]、decade[十年]、coco[椰树],注:abcde-decab-abcde这种不算死循环串)。现在zzx想请你帮忙在他随机生成的n个字符串中,用那个字符串作为开头可以让city寻找最多的字符串再进入死循环串。
输入
输入数据有多组,输入到文件结束为止。
第一个有一个正整数n(3<=n<=50000),表示有n个字符串
后接n行zzx随机生成的字符串s(3<=|s|<=20,只包含小写字母)
数据保证至少有一个死循环串和一个以死循环串开头两字母结尾的字母串,所有数据的n的和小于366666。
输出
一个字符串,使得以这个字符串作为开头可以让city寻找最多的字符串,若存在多个最小的按字典序最小输出。
样例输入
5
tenth
thirteenth
postulate
third
length
样例输出
postulate
提示
[假设]postulate-tenth-thirteenth.
数据不保证字符串不相同,这里假定相同的当作一个处理。
题解
然后在以死循环串为起点进行广度优选遍历,找到最后遍历的字符串(相同深度主要字典序最小)输出即为最远的
代码
#include<bits/stdc++.h> using namespace std; int n; struct node { int num,step; }u,d; queue<node> q; struct edge { char ch,ch1,ch2,ch3; char s[25]; }e[50005]; vector<int> G[3000]; int vis[50005],flag,maxlen; char start[25]; void bfs() { maxlen=0; strcpy(start,e[q.front().num].s); while(!q.empty()) { u=q.front(); q.pop(); if(u.step>maxlen) { maxlen=u.step; strcpy(start,e[u.num].s); } else if(strcmp(start,e[u.num].s)>0) { strcpy(start,e[u.num].s); } int num=(e[u.num].ch-'a')*100+e[u.num].ch1-'a'; for(int i=0;i<G[num].size();i++) { d.num=G[num][i]; if(vis[d.num]==0) { vis[d.num]=1; d.step=u.step+1; q.push(d); } } } } int main() { while(~scanf("%d",&n)) { memset(vis,0,sizeof(vis)); for(int i=1;i<=n;i++) { scanf("%s",e[i].s); int len=strlen(e[i].s); e[i].ch=e[i].s[0],e[i].ch1=e[i].s[1]; e[i].ch2=e[i].s[len-2],e[i].ch3=e[i].s[len-1]; if(e[i].ch==e[i].ch2&&e[i].ch1==e[i].ch3) { vis[i]=1; u.num=i;u.step=0; q.push(u); } else { G[(e[i].ch2-'a')*100+e[i].ch3-'a'].push_back(i); } } bfs(); printf("%s\n",start); for(int i=0;i<3000;i++) G[i].clear(); } }
浙公网安备 33010602011771号