题目描述
给定n个各不相同的无序字母对(区分大小写,无序即字母对中的两个字母可以位置颠倒)。请构造一个有n+1个字母的字符串使得每个字母对都在这个字符串中出现。
输入输出格式
输入格式:
第一行输入一个正整数n。
以下n行每行两个字母,表示这两个字母需要相邻。
输出格式:
输出满足要求的字符串。
如果没有满足要求的字符串,请输出“No Solution”。
如果有多种方案,请输出前面的字母的ASCII编码尽可能小的(字典序最小)的方案
输入输出样例
说明
【数据规模与约定】
不同的无序字母对个数有限,n的规模可以通过计算得到。
首先看题目要求,要求用n+1个字符表示出n个字母对(无序)
那么仔细想一下,首尾相接也就是一个环
考虑n个字母对就相当于n条边,字母相当于点
而又不重复,我们想到了什么?
对,欧拉路(欧拉回路)
我们在字母对之间建无向边,然后求欧拉路(欧拉回路),就是答案
但是要注意,求欧拉路(欧拉回路)的首要条件是这个图已知是欧拉图
对于判无解的情况,即这个图不是欧拉图。
判断无向图是不是欧拉图可以参见我的OK
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cmath> 5 #include<queue> 6 #include<map> 7 #define ll long long 8 #define DB double 9 #define eps 1e-3 10 #define inf 1847524821 11 #define u p[s[0]] 12 #define v p[s[1]] 13 using namespace std; 14 inline int read() 15 { 16 int x=0,w=1;char ch=getchar(); 17 while(!isdigit(ch)){if(ch==‘-‘) w=-1;ch=getchar();} 18 while(isdigit(ch)) x=(x<<3)+(x<<1)+ch-‘0‘,ch=getchar(); 19 return x*w; 20 } 21 const int N=1020; 22 int n,du[N],a[N][N],ans[N],k,S; 23 map<char,int>p; 24 map<int,char>h; 25 char s[30]; 26 void dfs(int x) 27 { 28 for(int i=1;i<=256;++i) 29 if(a[x][i]>=1) 30 { 31 a[x][i]--;a[i][x]--; 32 dfs(i); 33 } 34 ans[++k]=x; 35 } 36 int main() 37 { 38 for(int i=0;i<=255;++i)p[char(i)]=i+1,h[i+1]=char(i); 39 n=read(); 40 for(int i=1;i<=n;++i) 41 { 42 scanf("%s",s); 43 a[u][v]=a[v][u]=1; 44 du[u]++;du[v]++; 45 } 46 int fg=0; 47 for(int i=1;i<=256;++i) 48 { 49 if(du[i]==0) continue; 50 if(S==0 && du[i]%2==0) S=i; 51 if(du[i]%2) fg=1; 52 } 53 if(fg) 54 { 55 fg=0; 56 for(int i=1;i<=256;++i) 57 { 58 if(du[i]==0) continue; 59 if(du[i]%2) fg++; 60 } 61 if(fg && fg>2){printf("No Solution");return 0;} 62 S=0;fg=0; 63 for(int i=1;i<=256;++i) 64 { 65 if(du[i]==0) continue; 66 if(du[i]%2 && !fg) fg++,S=i; 67 } 68 } 69 dfs(S); 70 if(k<n+1) printf("No Solution"); 71 else{ 72 for(int i=k;i>=1;--i) 73 cout<<h[ans[i]]; 74 } 75 return 0; 76 }
(?′?‵?)I L???????