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 }

 

转载于:https://www.cnblogs.com/windysai/archive/2013/04/24/3039342.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值