首先,我们来看看题目:
Problem Description
呃......变形课上Harry碰到了一点小麻烦,因为他并不像Hermione那样能够记住所有的咒语而随意的将一个棒球变成刺猬什么的,但是他发现了变形咒语的一个统一规律:如果咒语是以a开头b结尾的一个单词,那么它的作用就恰好是使A物体变成B物体.
Harry已经将他所会的所有咒语都列成了一个表,他想让你帮忙计算一下他是否能完成老师的作业,将一个B(ball)变成一个M(Mouse),你知道,如果他自己不能完成的话,他就只好向Hermione请教,并且被迫听一大堆好好学习的道理.
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.Harry 可以念这个咒语:"big-got-them".HintHint
由于我刚上大学才接触C++,这种对别人来说相对水的DFS题目给我做也是需要纠结好久的。这是我纠结了2个小时左右给出的解答:
#include<iostream>
#include<string>
#include<vector>
using namespace std;
bool dfs(char);
vector<char> T,E;
int main()
{
string wor;
for(; cin>>wor; )
{
if(wor=="0")
break;
T.push_back (wor[0]);
E.push_back (wor[wor.size()-1]);
}
if(dfs('b'))
cout<<"Yes.";
else
cout<<"No.";
return 0;
}
bool dfs(char a)
{
if(a=='m')
return 1;
for(int i=0; i<T.size(); i++ )
{
if(T[i]==a)
{
char b=E[i];
if(dfs(b))
return 1;
}
}
return 0;
}
提交第二次后,出现了一个让我一看到就头疼的问题,“Runtime Error(STACK_OVERFLOW)”。这个问题我以前也遇到过,但是就没有解决过。于是,我就找了一位AC的同学的代码来看了看。因为根据上课所学的知识,栈溢出一般都是因为重复调用函数的过程中不断地在栈中给数据开辟空间,使得有限的栈空间用光了,于是就爆栈了。我拿着我的代码和同学的代码,仔细对比dfs函数的每一行,发现它唯一跟我不同的地方就是,它在主函数外加了一个全局变量,这个全局变量用来标记被访问过的单词,使得它们在dfs函数的多次重复调用中不会重复地使用。这样就减少了栈空间的消耗,因此提交后就顺利AC了。
下面是AC的代码:
#include<iostream>
#include<string>
#include<vector>
using namespace std;
bool dfs(char);
vector<char> T,E;
int jud[1000]={0};
int main()
{
string wor;
for(; cin>>wor;)
{
if(wor=="0")
break;
T.push_back (wor[0]);
E.push_back (wor[wor.size()-1]);
for(; cin>>wor; )
{
if(wor=="0")
break;
T.push_back (wor[0]);
E.push_back (wor[wor.size()-1]);
}
if(dfs('b'))
cout<<"Yes."<<endl;
else
cout<<"No."<<endl;
T.clear();
E.clear();
memset(jud,0,1000);
}
return 0;
}
bool dfs(char a)
{
if(a=='m')
return 1;
for(int i=0; i<T.size(); i++ )
{
if(T[i]==a&&jud[i]==0)
{
char b=E[i];
jud[i]=1;
if(dfs(b))
return 1;
}
}
return 0;
}
通过做这一道题目,我体会到了当我们需要多次利用函数进行递归时,应当考虑多次递归的过程中是否有大量的重复的无意义的递归。比如上题,递归过程很简单,但是如果按照我之前的代码就会产生多次重复的工作,使得栈内生成很多个没有意义的递归过程。而后面加了一个用来判断的数组,使得诸如:bomb-bomb-bomb-……这种无限递归和young-guy-young-guy-……这种无意义的递归被排除掉,于是就能得出正确的答案。