题意:
给定n个各不相同的无序字母对(区分大小写,无序即字母对中的两个字母可以位置颠倒)。请构造一个有n+1个字母的字符串使得每个字母对都在这个字符串中出现。
解法:
一道欧拉回路的模板题。将每个字母两两之间连一条无向边,然后求欧拉回路(保证字典序最小)。
#include<iostream> #include<stack> #define N 60 #define tint(_) (int(_-'A')) #define tchar(_) (char(_+'A')) using namespace std; bool e[N][N]={0}; int n,d[N],f[N],s; stack<int> st; void out(); void dfs(int x); void finds(); int fnd(int x); void uni(int x,int y); bool check(); void init(); int main() { init(); if(check()) { cout<<"No Solution"; return 0; } finds(); dfs(s); out(); return 0; } void out() { while(!st.empty()) { cout<<tchar(st.top()); st.pop(); } } void init() { cin>>n; for(int i=0;i<=N;i++) f[i]=i; for(int i=1;i<=n;i++) { char zu,zv; int u,v; cin>>zu>>zv; u=tint(zu); v=tint(zv); d[u]++; d[v]++; uni(u,v); e[u][v]=1; e[v][u]=1; } } bool check() { int j=0,now=0,fa; for(int i=0;i<=N;i++) if(d[i]%2==1) j++; if(j&&j!=2) return 1; while(!d[now++]); now--; fa=fnd(now); for(int i=now+1;i<=N;i++) if(d[i]&&fnd(i)!=fa) return 1; return 0; } int fnd(int x) { if(f[x]==x) return x; return f[x]=fnd(f[x]); } void uni(int x,int y) { if(fnd(x)!=fnd(y)) f[fnd(x)]=fnd(y); } void finds() { s=0; for(int i=0;i<=N;i++) if(d[i]%2==1) { s=i; break; } if(n==1) s=0; if(!s) for(int i=0;i<=N;i++) if(d[i]) { s=i; return; } } void dfs(int x) { for(int i=0;i<=N;i++) if(e[x][i]) { e[x][i]=0; e[i][x]=0; dfs(i); } st.push(x); }