题意:给出几个词语,问能不能接龙。
一开始猜只要所有字母连通,并且只有一个字母出现在开头次数为奇,一个字母末尾为奇,其它偶,就行。后来发现全为偶也行。而且条件也不对,比如ac,ac,ac就不行。实际上是一个字母在开头的次数比在末尾的次数多1,一个少1.
//#pragma comment(linker,"/STACK:1024000000,1024000000") #include<iostream> #include<cstdio> #include<string> #include<cstring> #include<vector> #include<cmath> #include<queue> #include<stack> #include<map> #include<set> #include<algorithm> #include <stack> using namespace std; typedef long long lon; const lon SZ=26,INF=0x7FFFFFFF; int arr[SZ],in[SZ],out[SZ]; void init() { for(int i=0;i<SZ;++i)arr[i]=i; } int find(int x) { return arr[x]==x?x:arr[x]=find(arr[x]); } void adj(int x,int y) { int rtx=find(x),rty=find(y); arr[rtx]=rty; } bool apr[26]; bool in_the_same_set(vector<string> &vct) { init(); memset(apr,0,sizeof(apr)); for(int i=0;i<vct.size();++i) { int a=vct[i][0]-'a'; int b=vct[i][vct[i].size()-1]-'a'; apr[a]=apr[b]=1; adj(a,b); } int rt=-1; for(int i=0;i<26;++i) { if(apr[i]) { if(rt==-1)rt=find(i); else { if(find(i)!=rt)return 0; } } } return 1; } bool work() { memset(in,0,sizeof(in)); memset(out,0,sizeof(out)); int n; cin>>n; vector<string> vct; for(int i=0;i<n;++i) { string str; cin>>str; vct.push_back(str); ++in[str[0]-'a']; ++out[str[str.size()-1]-'a']; } int head=0,tail=0,nh=0,nt=0; for(int i=0;i<26;++i) { if(in[i]==out[i]); else if(in[i]>out[i]) { if(in[i]==out[i]+1)head=i,++nh; else return 0; } else { if(out[i]==in[i]+1)tail=i,++nt; else return 0; } //if(in[i]&1) //if(out[i]&1) } //cout<<" "<<nh<<" "<<nt<<endl; if(nh+nt>2)return 0; else { return in_the_same_set(vct); } } int main() { std::ios::sync_with_stdio(0); //freopen("d:\\1.txt","w",stdout); lon casenum; cin>>casenum; for(lon time=1;time<=casenum;++time) //for(;scanf("%d",&n)!=EOF;) { if(work())cout<<"Ordering is possible."<<endl; else cout<<"The door cannot be opened."<<endl; } return 0; }