无序字母对
题目描述
给定n个各不相同的无序字母对(区分大小写,无序即字母对中的两个字母可以位置颠倒)。请构造一个有n+1个字母的字符串使得每个字母对都在这个字符串中出现。
输入输出格式
输入格式:第一行输入一个正整数n。
以下n行每行两个字母,表示这两个字母需要相邻。
输出格式:输出满足要求的字符串。
如果没有满足要求的字符串,请输出“No Solution”。
如果有多种方案,请输出前面的字母的ASCII编码尽可能小的(字典序最小)的方案
输入输出样例
输入样例#1:
4 aZ tZ Xt aX
输出样例#1:
XaZtX
说明
【数据规模与约定】
不同的无序字母对个数有限,n的规模可以通过计算得到。
思路
问题可以转化为寻找欧拉通路或是欧拉回路;
把图中每一个字母看做一个图中的节点;
答案的含义即为以较小字典序端点开始的欧拉通路或是以最小字典序节点开始的欧拉回路;
代码实现
1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 inline int min_(int x,int y){return x<y?x:y;} 5 inline int max_(int x,int y){return x>y?x:y;} 6 int n,hs=1,pro; 7 int h[3000],ld[3000],ed[3000][3000],es[3000]; 8 char a,b,s,t,q,ch[5]; 9 bool v[3000][3000],ans; 10 int lj[3000]; 11 void dfs(char k,int d){ 12 if(d>n){ans=1;return;} 13 for(int i=0;i<es[k];i++) 14 if(!v[k][ed[k][i]]&&!v[ed[k][i]][k]){ 15 v[k][ed[k][i]]=1; 16 lj[d]=ed[k][i]; 17 dfs(ed[k][i],d+1); 18 v[k][ed[k][i]]=0; 19 if(ans) return; 20 } 21 } 22 int main(){ 23 scanf("%d",&n);s='z'; 24 for(int i=1;i<=n;i++){ 25 scanf("%s",ch); 26 a=ch[0],b=ch[1]; 27 q=s=min_(s,min_(a,b)); 28 t=max_(t,max_(a,b)); 29 ed[a][es[a]++]=b; 30 ed[b][es[b]++]=a; 31 ++ld[a],++ld[b]; 32 } 33 for(int i=t;i>=s;i--){ 34 if(ld[i]&1) q=i,pro++; 35 sort(ed[i],ed[i]+es[i]); 36 } 37 if(pro&&pro!=2) puts("No Solution"); 38 else{ 39 dfs(q,1); 40 printf("%c",q); 41 for(int i=1;i<=n;i++) printf("%c",lj[i]); 42 } 43 return 0; 44 }
用边表!!!sort排好序。。。