Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 12658 | Accepted: 3274 |
Description
A catenym is a pair of words separated by a period such that the last letter of the first word is the same as the last letter of the second. For example, the following are catenyms:
A compound catenym is a sequence of three or more words separated by periods such that each adjacent pair of words forms a catenym. For example,
aloha.aloha.arachnid.dog.gopher.rat.tiger
Given a dictionary of lower case words, you are to find a compound catenym that contains each of the words exactly once.
dog.gopher
gopher.rat
rat.tiger
aloha.aloha
arachnid.dog
A compound catenym is a sequence of three or more words separated by periods such that each adjacent pair of words forms a catenym. For example,
aloha.aloha.arachnid.dog.gopher.rat.tiger
Given a dictionary of lower case words, you are to find a compound catenym that contains each of the words exactly once.
Input
The first line of standard input contains t, the number of test cases. Each test case begins with 3 <= n <= 1000 - the number of words in the dictionary. n distinct dictionary words follow; each word is a string of between 1 and 20 lowercase letters on a line by itself.
Output
For each test case, output a line giving the lexicographically least compound catenym that contains each dictionary word exactly once. Output "***" if there is no solution.
Sample Input
2
6
aloha
arachnid
dog
gopher
rat
tiger
3
oak
maple
elm
Sample Output
aloha.arachnid.dog.gopher.rat.tiger
***
Source
题意:给你一些单词,请你判断能否把他们首尾串起来串成一串,
前一个单词的结尾字母应该与下一个单词的首字母相同。
并且输出所有方案中字典序最小的方案。
吐槽:一直CE的我不想调他了,如果有大佬路过,可以帮忙看一下嘛?(*^__^*) 嘻嘻……
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define MAXN 101000 using namespace std; int sum1,sum2; int t,n,sum,tot,anss; int out[30],into[30]; string s[MAXN],ans[MAXN]; int fa[30],vi[MAXN],vis[30],num[MAXN]; int to[MAXN],net[MAXN],head[MAXN]; void add(int u,int v){ to[++tot]=v;net[tot]=head[u];head[u]=tot; } int cmp(string a,string b){ return a<b; } int find(int x){ if(fa[x]==x) return fa[x]; return fa[x]=find(fa[x]); } void dfs(int now,int id){ for(int i=head[now];i;i=net[i]) if(!vi[i]){ vi[i]=1; dfs(to[i],i); } if(id!=-1) ans[++anss]=s[id]; } int main(){ scanf("%d",&t); while(t--){ scanf("%d",&n); sum=sum1=sum2=0;tot=0; memset(to,0,sizeof(to)); memset(net,0,sizeof(net)); memset(vis,0,sizeof(vis)); memset(out,0,sizeof(out)); memset(head,0,sizeof(head)); memset(into,0,sizeof(into)); for(int i=1;i<=26;i++) fa[i]=i; for(int i=1;i<=n;i++) cin>>s[i]; sort(s+1,s+1+n,cmp); for(int i=1;i<=n;i++){ int x=s[i][0]-‘a‘+1; int y=s[i][s[i].length()-1]-‘a‘+1; out[x]++; into[y]++; vis[x]=1; vis[y]=1; add(x,y); int dx=find(x); int dy=find(y); if(dx!=dy) fa[dy]=dx; } for(int i=1;i<=26;i++) if(vis[i]&&fa[i]==i) sum++; if(sum>1){ cout<<"***"<<endl;continue; } sum=0; for(int i=1;i<=26;i++) if(vis[i]&&into[i]!=out[i]){ sum++; if(into[i]-1==out[i]) sum1=i; if(into[i]==out[i]-1) sum2=i; } if(sum==0){ for(int i=1;i<=26;i++) if(vis[i]){ dfs(i,-1);break; } } else if(sum1&&sum2&&sum==2) dfs(sum2,-1); else{ cout<<"***"<<endl;continue; } cout<<ans[anss]; for(int i=anss-1;i>=1;i--) cout<<"."<<ans[i]; cout<<endl; } }