题目:
呃…变形课上Harry碰到了一点小麻烦,因为他并不像Hermione那样能够记住所有的咒语而随意的将一个棒球变成刺猬什么的,但是他发现了变形咒语的一个统一规律:如果咒语是以a开头b结尾的一个单词,那么它的作用就恰好是使A物体变成B物体.
Harry已经将他所会的所有咒语都列成了一个表,他想让你帮忙计算一下他是否能完成老师的作业,将一个B(ball)变成一个M(Mouse),你知道,如果他自己不能完成的话,他就只好向Hermione请教,并且被迫听一大堆好好学习的道理。
Input
测试数据有多组。每组有多行,每行一个单词,仅包括小写字母,是Harry所会的所有咒语.数字0表示一组输入结束.
Output
如果Harry可以完成他的作业,就输出"Yes.",否则就输出"No."(不要忽略了句号)
Sample Inputso
soon
river
goes
them
got
moon
moon
begin
big
0
Sample Output
Yes.
Harry 可以念这个咒语:“big-got-them”.
这个题是一个多组测试题,处理到文件结束,并且每一组数据以0结束,这个题在解决问题使用深度优先搜索方法,一开始我把题打完结果是超时,后来才意识到这个不应该是无限组输入,是处理到文件结束的,所以一开始要用while循环判定输入的一组数据的开头是不是处理到文件结束(Ctrl+z结束),这里我使用二维数组,开一个全局二维数组(因为这个数组很大而且还要使用在深搜的函数中),一组单词中可能有很多个字母b开头的单词,循环判断如果是b开头的字母进入dfs函数,函数运行结束如果flag为1(也就是这个单词开始能完成作业)就跳出循环不用再去找下一个b开头的单词了(在这里增加一次判断可以节省时间),如果不是则继续寻找,在dfs函数中接受一个参数,也就是这个单词的序号,函数中首先判断当前序号单词最后的字母是否为m,如果为m则可以完成作业,将flag设置为1,如果不能则进入循环,寻找首字母与当前序号单词尾字母相同的单词,被选中的单词用book标记,继续调用dfs函数搜索。
代码:
#include<bits/stdc++.h>
using namespace std;
int book[200];
int flag=0;
char a[200][100];
int number;
void dfs(int num)
{
if(a[num][strlen(a[num])-1]=='m')//如果当前序号单词尾字母为m,则将flag设置为1
{
flag=1;
}
for(int i=0;i<number;i++)//寻找与当前单词能首尾相接的单词
{
if(book[i]==0&&a[num][strlen(a[num])-1]==a[i][0])
{
book[i]=1;
dfs(i);
book[i]=0;
}
if(flag==1)
break;
}
}
int main()
{
char s[100];
while(scanf("%s",s)!=EOF)//判断是否处理到文件结束
{
flag=0;
memset(book,0,sizeof(book));//book清零
memset(a,0,sizeof(a));//字符数组a清零
if(strcmp(s,"0")==0)
continue;
else
{
strcpy(a[0],s);//将第一个单词加入数组
}
for(int i=1;i<100;i++)
{
cin>>a[i];
if(strcmp(a[i],"0")==0)
{
number=i;
break;
}
}
for(int i=0;i<number;i++)
{
if(a[i][0]=='b')//如果单词开头是b就进入搜索
{
book[i]=1;//先标记为已使用
dfs(i);
book[i]=0;
}
if(flag==1)
break;
}
if(flag==1)
cout<<"Yes."<<endl;
else
cout<<"No."<<endl;
}
return 0;
}