HDU 1181(简单dfs)

变形课

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)
Total Submission(s): 24615    Accepted Submission(s): 8962


Problem Description
呃......变形课上Harry碰到了一点小麻烦,因为他并不像Hermione那样能够记住所有的咒语而随意的将一个棒球变成刺猬什么的,但是他发现了变形咒语的一个统一规律:如果咒语是以a开头b结尾的一个单词,那么它的作用就恰好是使A物体变成B物体.
Harry已经将他所会的所有咒语都列成了一个表,他想让你帮忙计算一下他是否能完成老师的作业,将一个B(ball)变成一个M(Mouse),你知道,如果他自己不能完成的话,他就只好向Hermione请教,并且被迫听一大堆好好学习的道理.
 

Input
测试数据有多组。每组有多行,每行一个单词,仅包括小写字母,是Harry所会的所有咒语.数字0表示一组输入结束.
 

Output
如果Harry可以完成他的作业,就输出"Yes.",否则就输出"No."(不要忽略了句号)
 

Sample Input
  
  
so soon river goes them got moon begin big 0
 

Sample Output
  
  
Yes.
Hint
Hint
Harry 可以念这个咒语:"big-got-them".
 算法思路很简单,就是一个个的去找,先找到首字母为b的单词,从这些首字母为b的单词出发,对于每一个首字母为b的单词,你第一步是看它的末尾字母是不是m,若是m则查找结束,输出"Yes." ,如果末尾字母不是m,则你就得搜索了。搜索的步骤是,对于每个单词给它们标记为0,对于可以“接入”单词串中的单词置为1,其它单词若加入了这个咒语串中则置为1。对于这个起始的单词,由于尾单词不是m, 故我们需要在标记为0的单词中找到某个单词使得该单词的首单词是上一个单词的尾单词,没找到一个这样的单词,我们都需要判断它的末尾单词是不是m, 若是m则说明我们可以通过单词的连接,来得到这个咒语,说明可行,输出"Yes."。 但所有的这些以b开头的单词都不能同过这样的步骤得到上结果,说明无论怎么单词拼接都不能满足题意,所以说出"No."
#include<iostream>
#include <string>
#include <cstring>
#include <algorithm>
#define N 1010

using namespace std;
int vis[N];
string str[N];
int k;

bool dfs(int op)
{
    vis[op] = 1;                //这个可以拼接在咒语串中,置为1,防止重复访问,和死循环
    int len = str[op].length();
    if(str[op][len-1] == 'm')       //递归的终止条件
        return true;
    else
    {
        for(int i = 0; i < k; i++)        //一个一个的去找
        {
            if(vis[i]) continue;  //若这个单词以拼接过则跳过,不然会出现环,甚至使程序陷入死循环
            if(str[i][0] == str[op][len - 1])     //若找到一个单词的首字母与上一个拼接的单词尾单词相同,则发现这个问题是一个递归问题,所以接下来用递归(这一步
            {                                     //是dfs的核心,找出深搜的下一个对象。
                if(dfs(i))
                    return true;
                vis[i] = 0;                          //切记一定要将标记改回来,清除标记!!!

            }
        }
    } 
    return false;
}
int main()
{ 
    k = 0; 
    int flag = 0; 
    memset(vis, 0, sizeof(vis)); 
    string s; 
    while(cin >> s) 
    { 
        if(s[0] == '0') 
        { 
            for(int i = 0; i < k; i++) 
            { 
                if(str[i][0] == 'b') 
                { 
                    if(dfs(i)) 
                    { 
                        cout << "Yes." << endl; 
                        flag = 1; 
                        break; 
                    } 
                } 
            } 
            if(!flag) 
            { 
                cout << "No." << endl; 
            } 
            k = 0; //对于多组数据,故每次要更新这几个值 
            flag = 0; 
            memset(vis, 0, sizeof(vis)); 
        }
        else 
        { 
            str[k++] = s; 
        } 
    } 
    return 0;
}




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值