hdu 1181 变形课 解题报告
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1181
又一条深搜,但是我做的时候根本没有想到用dfs做,应该是数学模型还没建立好吧!结果就是只能实现部分功能。我的做法是:由于只用到一个单词的首尾两个字母,所以很自然的想到用结构体来保存;接着比较所有输进的单词(直到出现结束标志'0'),默认的比较应该是按首字母的字典序升序排列吧(排序是为了下面操作方便);然后通过for语句找,找一个首字母为'b'的,找到就保存这个单词的尾部, 接着试图想拿这个单词的尾部覆盖首字母是b的那个单词......但是问题出现了,下一个循环找要怎么写?到这里我就卡机了,我的代码是从当前的那个单词往下找,但是发现会漏了这个单词前面能够匹配的情况。例如ca, bc, aw, wt,tm 这种情况本来是有解的,但是由于不能再往前找,所以无解!!另外一个错误就是只能处理不包含相同首字母的情况。
例如这组输入:
so soon river goes them got moon begin big
保存的序列:
bn bg gs gt mn rr so sn tm
因为只会搜寻一次,有两个g的情况,只会处理第一个g(gs),第二个g(gt,通向结果的道路) 不会再处理,如果gs gt位置互换,那么是能够得到结果的。所以我的代码存在致命的错误啊。
网上看到用传递闭包、并查集、dfs做,但前两种由于我还没接触,所以就借鉴人家dfs的做法。
说真的,通过这道题目,我发现我没真正理解dfs的精髓,之前做的几道发现是迷迷糊糊做的,具体的递归调用,栈的结构:后进先出。 真的让我很难理解。恶补了一下这些知识,再加上那位好好人的师兄majia的超有耐心的教导,算是比较理解了。
1 #include <iostream> 2 #include <string.h> 3 using namespace std; 4 5 int n; 6 bool visit[100]; 7 8 struct words 9 { 10 char head, tail; 11 } word[101]; 12 13 bool dfs(char ch) 14 { 15 int i; 16 if (ch == 'm') 17 return 1; 18 for (i = 0; i < n; i++) 19 { 20 if (!visit[i] && ch == word[i].head) 21 { 22 visit[i] = 1; //找到则标记1,防止下一次再找 23 if (dfs(word[i].tail)) //用找到的那个单词的尾部覆盖,作为新的单词找下一个满足等于它的尾部的字母的单词,找不到就递归往回退,直到找到为止 24 return 1; 25 visit[i] = 0; //找不到则标记0,往回退 26 } 27 } 28 return 0; 29 } 30 31 int main() 32 { 33 char a[100]; 34 while (cin >> a) 35 { 36 n = 0; 37 while (a[0] != '0') 38 { 39 word[n].head = a[0]; 40 word[n].tail = a[strlen(a)-1]; 41 n++; 42 cin >> a; 43 } 44 memset(visit, 0, sizeof(visit)); 45 if (dfs('b')) 46 printf("Yes.\n"); 47 else 48 printf("No.\n"); //如果找遍所有单词都没有找到,就输出'No' 49 } 50 return 0; 51 }
2014.7.21 再写的(因为搜索太差了,先把以前没有做出的,但看别人做对的题目重新做过!!!),想不到没留意到题目中说的“测试数据有多组” 而wa了几次。
1 #include <iostream> 2 #include <cstdio> 3 #include <stdio.h> 4 #include <cstdlib> 5 #include <cstring> 6 using namespace std; 7 8 const int maxn = 5000 + 10; 9 char s[maxn]; 10 int flag, l, vis[maxn]; 11 12 struct node 13 { 14 char start, end; 15 }ball[maxn]; 16 17 void dfs(char ch) 18 { 19 if (ch == 'm') 20 { 21 flag = 1; 22 return; 23 } 24 for (int i = 0; i < l; i++) 25 { 26 if (ch == ball[i].start && !vis[i]) 27 { 28 vis[i] = 1; 29 dfs(ball[i].end); 30 vis[i] = 0; 31 } 32 } 33 } 34 35 int main() 36 { 37 while (cin >> s) 38 { 39 l = 0; 40 flag = 0; 41 memset(vis, 0, sizeof(vis)); 42 while (s[0] != '0') 43 { 44 int len = strlen(s); 45 ball[l].start = s[0]; 46 ball[l].end = s[len-1]; 47 l++; 48 cin >> s; 49 } 50 dfs('b'); 51 printf("%s\n", flag ? "Yes." : "No."); 52 } 53 return 0; 54 }