uva10129- Play on Words(单词)
做题还是得站在原有结论的基础上,否则很浪费时间的。就像这次,开始的时候想自己想办法判通路,但是没有成功,后来看了欧拉判断法则,才把程序写出来。
代码如下:
#include <stdio.h> #include <string.h> int str[27][27], visit[27], du[27][2];//用数组记录字母的出度与入度 void read() {//读取字符串,记录开头与结尾的字母 int n; char por, tear, temp; scanf("%d",&n); getchar(); while(n--) { scanf("%c",&por); du[por-'a'][1]++; while((temp=getchar())!='\n') tear = temp; du[tear-'a'][0]++; str[por-'a'][tear-'a'] = 1; } } void dfs(int s) {//深搜,找是否有通路 visit[s] = 1; for(int i = 0; i < 26; i++) { if(str[s][i]&&!visit[i]) dfs(i); } } int solve() { int head = -1, tear = -1; for(int i = 0,count = 0; i < 26; i++) {//检查出度与入度,是否满足出度与入度相等,否则最多相差1. if(du[i][0] != du[i][1]) { if(du[i][0]-du[i][1]>=2&&du[i][0]-du[i][1]<=-2)return 0; else { count++; if(du[i][1]-du[i][0]==1) head = i; else tear = i; } } if(count>2)return 0;//如果出现多个入度与出度相差1的节点,则肯定不能有且只有一条通路 } if(head==-1&&tear==-1)//如果是欧拉回路的话 { for(int i = 0; i < 26; i++) if(du[i][0]){dfs(i); break;} } else if(head==-1||tear==-1)return 0;//如果不满足条件“开头节点出度比入度大1和结尾的节点出度比入度小1” else dfs(head);//否则就从头开始搜索 for(int i = 0; i < 26; i++) if(((du[i][0]+du[i][1])&&visit[i])||(!(du[i][0]+du[i][1])&&!visit[i]));//看其是否为通路(即有度的节点必须访问到) else return 0; return 1; } int main () { int t; scanf("%d",&t); while(t--) { memset(str, 0, sizeof(str)); memset(visit,0,sizeof(visit)); memset(du, 0, sizeof(du)); read(); if(solve())puts("Ordering is possible."); else puts("The door cannot be opened."); } return 0; }