Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 10681 | Accepted: 2788 |
Description
dog.gopher gopher.rat rat.tiger aloha.aloha arachnid.dog
Input
Output
Sample Input
2 6 aloha arachnid dog gopher rat tiger 3 oak maple elm
Sample Output
aloha.arachnid.dog.gopher.rat.tiger***
解体思路:WA了无数遍终于ac了.主要是要理解如何寻找欧拉回路--套圈法.附上网上对这种方法的解释:对于欧拉图,从一个节点出发,随便往下走(走过之后需要标记一下,下次就不要来了),必然也在这个节点终止(因为除了起始节点,其他节点的度数都是偶数,只要能进去就能出来)。这样就构成了一个圈,但因为是随便走的,所以可能会有些边还没走过就回来了。我们就从终止节点逆着往前查找,直到找到第一个分叉路口,然后从这个节点出发继续上面的步骤,肯定也是可以找到一条回到这个点的路径的,这时我们把两个圈连在一起。当你把所有的圈都找出来后,整个欧拉回路的寻找就完成了。
代码如下:
#include<stdio.h> #include<string.h> #include<stack> #include<algorithm> using namespace std; stack<int>S; struct stu{ char s[25]; int t,ne; }; stu edge[1010]; int path[1010]; int vist[1010]; int exist[30]; int id[30]; int od[30]; int head[30]; int num; int cmp(stu a,stu b){ return strcmp(a.s,b.s)>0; } void dfs(int x){ for(int i=head[x];i!=-1;i=edge[i].ne){ if(!vist[i]){ vist[i]=1; dfs(edge[i].t); path[num++]=i; } } } int main(){ int t,n,star; scanf("%d",&t); while(t--){ scanf("%d",&n); for(int i=0;i<n;i++){ scanf("%s",edge[i].s); } sort(edge,edge+n,cmp); memset(exist,0,sizeof(exist)); memset(id,0,sizeof(id)); memset(od,0,sizeof(od)); memset(head,-1,sizeof(head)); memset(vist,0,sizeof(vist)); star=30; for(int i=0;i<n;i++){ int l=strlen(edge[i].s); int x=edge[i].s[0]-'a'; int y=edge[i].s[l-1]-'a'; //edge[i].f=x; edge[i].t=y; //edge[i].id=i; edge[i].ne=head[x]; head[x]=i; exist[x]=1; exist[y]=1; od[x]++; id[y]++; if(x<star)star=x; if(y<star)star=y; } // for(int i=0;i<n;i++) // printf("%s\n",edge[i].s); int sum=0; int ans=0; int a1=0; int a2=0; for(int i=0;i<30;i++){ if(exist[i]){ ans++; if(id[i]==od[i]){ sum++; } if(id[i]-od[i]==1){ a1=1; } if(od[i]-id[i]==1){ a2=1; star=i; } } } if(sum==ans||(sum==ans-2&&a1&&a2)){ num=0; dfs(star); if(num!=n){ printf("***\n"); } else{ printf("%s",edge[path[num-1]].s); for(int i=num-2;i>=0;i--){ printf(".%s",edge[path[i]].s); } printf("\n"); } } else printf("***\n"); } return 0; }