标签:大小 表示 通过 数据 思路 dfs oid printf ++
给定n个各不相同的无序字母对(区分大小写,无序即字母对中的两个字母可以位置颠倒)。请构造一个有n+1个字母的字符串使得每个字母对都在这个字符串中出现。
第一行输入一个正整数n。
以下n行每行两个字母,表示这两个字母需要相邻。
输出格式:输出满足要求的字符串。
如果没有满足要求的字符串,请输出“No Solution”。
如果有多种方案,请输出前面的字母的ASCII编码尽可能小的(字典序最小)的方案
4 aZ tZ Xt aX
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 }
标签:大小 表示 通过 数据 思路 dfs oid printf ++
原文地址:http://www.cnblogs.com/J-william/p/6837875.html