变形课 有解析 HDU--1181

题目:

呃…变形课上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
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;
}

你可能感兴趣的:(变形课 有解析 HDU--1181)