洛谷 P1341 无序字母对 Label:欧拉路 一笔画
题目描述
给定n个各不相同的无序字母对(区分大小写,无序即字母对中的两个字母可以位置颠倒)。请构造一个有n+1个字母的字符串使得每个字母对都在这个字符串中出现。
输入输出格式
输入格式:
第一行输入一个正整数n。
以下n行每行两个字母,表示这两个字母需要相邻。
输出格式:
输出满足要求的字符串。
如果没有满足要求的字符串,请输出“No Solution”。
如果有多种方案,请输出前面的字母的ASCII编码尽可能小的(字典序最小)的方案
输入输出样例
输入样例#1:
4 aZ tZ Xt aX
输出样例#1:
XaZtX
说明
【数据规模与约定】
不同的无序字母对个数有限,n的规模可以通过计算得到。
代码
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<algorithm> 5 #define INF 0x3f3f3f3f 6 using namespace std; 7 int tot,p,N,x,y,k=INF; 8 int a[10005],c[10005],du[10005],b[105][105]; 9 char str[3]; 10 11 void dfs(int u){ 12 for(int i=0;i<58;i++){ //A到z之间还有一些字符,总共58个~ 13 if(b[u][i]){ 14 b[u][i]=b[i][u]=0; 15 dfs(i); 16 // break; 17 } 18 } 19 c[++tot]=u; 20 } 21 22 23 int main(){ 24 // freopen("01.in","r",stdin); 25 scanf("%d",&N); 26 for(int i=1;i<=N;i++){ 27 scanf("%s",str); 28 x=str[0]-'A',y=str[1]-'A';//字符串从0开始读入 29 k=min(k,min(x,y)); 30 b[x][y]=b[y][x]=1; 31 ++du[x],++du[y]; 32 } 33 for(int i=0;i<58;i++){ 34 if(du[i]&1){ 35 a[++p]=i; 36 } 37 } 38 39 if(p==0) dfs(k); 40 else if(p==2) dfs(a[1]); 41 else{ 42 puts("No Solution"); 43 return 0; 44 } 45 46 for(int i=tot;i>=1;i--){ 47 printf("%c",c[i]+'A'); 48 } 49 50 return 0; 51 }照例转载题解:
把两个字母拆成两个顶点 然后构造一个无向图 ,这样根据欧拉回路 当一个图中每个点的度数都是偶数时 纯在欧拉环 而只有2个奇数度数时,存在欧拉路径 因此先验证一下然后dfs 这里为了储存答案我用了双端队列,当然也可以不用 偷点懒,至于最小字典序的话 拍一下序就好了 而如果你用 vector的话 直接从小到大排序(我就是这么做的),而如果你用链表的号 需要首字母从小到大 第二个字母从大到小
我再说两句:
按照欧拉路的性质,若有度奇数点,只能从奇数点走,
本题中若没有则按照题意以Line39的处理方式从ASCII最小序走
特别注意!!!
Line16不可写!!!
这样不写处理的话字符串会以一种神奇的方式连接起来!!!,想想看为什么~
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 3.0 许可协议。转载请注明出处!