无序字母对
Posted 鄉勇
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了无序字母对相关的知识,希望对你有一定的参考价值。
题目描述
给定n个各不相同的无序字母对(区分大小写,无序即字母对中的两个字母可以位置颠倒)。请构造一个有n+1个字母的字符串使得每个字母对都在这个字符串中出现。
输入输出格式
输入格式:第一行输入一个正整数n。
以下n行每行两个字母,表示这两个字母需要相邻。
输出格式:输出满足要求的字符串。
如果没有满足要求的字符串,请输出“No Solution”。
如果有多种方案,请输出前面的字母的ASCII编码尽可能小的(字典序最小)的方案
输入输出样例
输入样例#1:
4 aZ tZ Xt aX
输出样例#1:
XaZtX
说明
【数据规模与约定】
不同的无序字母对个数有限,n的规模可以通过计算得到。
思路
问题可以转化为寻找欧拉通路或是欧拉回路;
把图中每一个字母看做一个图中的节点;
答案的含义即为以较小字典序端点开始的欧拉通路或是以最小字典序节点开始的欧拉回路;
代码实现
可能是我写法的问题,朴素的DFS只得了40分,其他T了。
1 #include<cstdio> 2 inline int min_(int x,int y){return x<y?x:y;} 3 inline int max_(int x,int y){return x>y?x:y;} 4 int n,hs=1,pro; 5 int h[3000],ld[3000]; 6 struct edge{int s,n;}e[300000]; 7 char a,b,s,t,Q1,Q2,ch[5]; 8 void add(int x,int y){e[++hs]=(edge){y,h[x]},h[x]=hs;} 9 bool v[300000],ans; 10 int lj[3000]; 11 void dfs(char k,int d){ 12 if(d>n){ 13 ans=1; 14 return; 15 } 16 for(int i=h[k];i;i=e[i].n) 17 if(!v[i]){ 18 v[i]=v[i^1]=1; 19 lj[d]=i; 20 dfs(e[i].s,d+1); 21 v[i]=v[i^1]=0; 22 if(ans) return; 23 } 24 } 25 int main(){ 26 scanf("%d",&n);s=‘z‘; 27 for(int i=1;i<=n;i++){ 28 scanf("%s",ch); 29 a=ch[0],b=ch[1]; 30 s=min_(s,min_(a,b)); 31 t=max_(t,max_(a,b)); 32 add(a,b),add(b,a); 33 ++ld[a]; 34 if(ld[a]&1){ 35 ++pro; 36 if(ld[Q1]&1) Q2=a; 37 else Q1=a; 38 } 39 else --pro; 40 ++ld[b]; 41 if(ld[b]&1){ 42 ++pro; 43 if(ld[Q1]&1) Q2=b; 44 else Q1=b; 45 } 46 else --pro; 47 } 48 if(pro&&pro!=2) puts("No Solution"); 49 else{ 50 if(pro==2) s=min_(Q1,Q2); 51 dfs(s,1); 52 printf("%c",s); 53 for(int i=1;i<=n;i++){ 54 printf("%c",e[lj[i]].s); 55 } 56 } 57 return 0; 58 }
以上是关于无序字母对的主要内容,如果未能解决你的问题,请参考以下文章