字符串拼接
水了一道欧拉路的题
题目是:
单词拼接
时间限制:3000 ms | 内存限制:65535 KB
时间限制:3000 ms | 内存限制:65535 KB
描述
给你一些单词,请你判断能否把它们首尾串起来串成一串。
前一个单词的结尾应该与下一个单词的道字母相同。
如
aloha
dog
arachnid
gopher
tiger
rat
可以拼接成:aloha.arachnid.dog.gopher.rat.tiger
输入第一行是一个整数N(0<N<20),表示测试数据的组数
每组测试数据的第一行是一个整数M,表示该组测试数据中有M(2<M<1000)个互不相同的单词,随后的M行,每行是一个长度不超过30的单词,单词全部由小写字母组成。
输出如果存在拼接方案,请输出所有拼接方案中字典序最小的方案。(两个单词之间输出一个英文句号".")
如果不存在拼接方案,则输出
***
样例输入
2
6
aloha
arachnid
dog
gopher
rat
tiger
3
oak
maple
elm
样例输出
aloha.arachnid.dog.gopher.rat.tiger
***
aloha.arachnid.dog.gopher.rat.tiger
***
代码实现:
#include <iostream> #include <cstring> #include <algorithm> using namespace std; const int N = 1010; struct word{ string s; char first,second; bool operator < (const word& w)const{ return first<w.first; } }words[N]; int d_in[30],d_out[30]; int pos[N]; int vi[N]; int getstart(){ int num1=0,num2=0,res; for(int i=0;i<26;i++){ if(d_in[i]-d_out[i]>1||d_out[i]-d_in[i]>1){ return -1; } if(d_in[i]-d_out[i]==1){ num1++; } if(d_out[i]-d_in[i]==1){ num2++; res=i; } } if(num1>1||num2>1)return -1; else if(num1==0&&num2==0){ return 0;//欧拉回路 } else { return res;//欧拉通路 } } bool dfs(int c,int f,int m){ if(c==m){ return true; } for(int i=0;i<m;i++){ if((words[i].first-'a')>f){ return false; } if((words[i].first-'a')==f&&!vi[i]){ vi[i]=1; pos[c]=i; if(dfs(c+1,words[i].second-'a',m)){ return true; } vi[i]=0; pos[c]=0; } } return false; } int main(){ int n; cin>>n; while(n--){ memset(vi,0,sizeof vi); memset(d_in,0,sizeof d_in); memset(d_out,0, sizeof d_out); memset(pos,-1,sizeof pos); int m; cin>>m; for(int i=0;i<m;i++){ string c; cin>>c; words[i].s=c; int len=c.size()-1; words[i].first=c[0]; words[i].second=c[len]; d_out[c[0]-'a']++; d_in[c[len]-'a']++; } sort(words,words+m); int k = getstart(); if(k==-1){ cout<<"***"<<endl; continue; } if(dfs(0,k,m)){ for(int i=0;i<m;i++){ cout<<words[pos[i]].s<<"."; } cout<<endl; } else cout<<"***"<<endl; } }

浙公网安备 33010602011771号