HDU 1181 变形课 广搜BFS记录字母表模拟做法

变形课

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


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".

       这是一个基础的搜索题,而我在网上做完后也在网上查了很多代码。我发现这个题的解法真的有好多啊!即使一样是用BFS的也有不同的方式记录输入,而更多的是有很多DFS 的代码。虽然思路上相同,但是,在细节上处理有很多种。而且更值得注意的是,随着细节上处理方式的不同它们写代码的长短也有很大差距。这也就正好与我当初的想法恰好吻合了,对于一个简单题不应该仅仅满足于AC应该要尽可能的使用更好的做法。我在我浏览了几个博客后又修改了我的BFD代码。(因为,在会了搜索的情况下思路很简单,所以就不说思路了。)


#include<iostream>
#include<string>
#include<cstring>

using namespace std;
char Sch[30][30];//是用这个来记录字母表。 
int  Cch[30];    //这个数组记录字母表中,每个字母可以变化的数量。 
bool SBch[30][30];//使用这个来加快的记录字母表的速度。 
//我使用的是广搜BFS做法。 
void bfs()
{
	char que[50];
	char bool_que[30];
	memset(bool_que,false,sizeof(bool_que));
	int st=0;
	int en=1;
	que[st]='b';
	bool_que['b'-'a']=true;
	while(st!=en){
		int c=que[st]-'a';
		for(int j=0;j<Cch[c];j++){
		/*对应每个头结点,把把符合要求的变化加入
		队列。即:1.这个字母可以所有变化。2.对于
		每种变化都必须是没有出现后的字母*/
			//cout<<Sch[c][j]<<" ";
			if(bool_que[Sch[c][j]-'a']==false){
				//cout<<Sch[c][j];
				que[en++]=Sch[c][j];
				bool_que[Sch[c][j]-'a']=true;
			}
		}
		//cout<<endl; 
		if(bool_que['m'-'a']){
			break;
		}
		st++;
	}
	if(bool_que['m'-'a'])
		cout<<"Yes."<<endl;
	else
		cout<<"No."<<endl;
}
int main()
{
	string s;
	while(cin>>s){
		if(s.length()==1&&s[0]=='0'){
		//当输入到0的时候表示一组数据输入完成开始BFS 
			/*for(int j=0;j<30;j++){
				for(int k=0;k<30;k++)
					cout<<Sch[j][k]<<" ";
				cout<<endl; 
			}*/
		/*使用上面这个能打印出字母表,能够
		看到每个字母分别能变化成什么字母*/
			bfs();
			memset(Sch,0,sizeof(Sch));
			memset(Cch,0,sizeof(Cch));
			memset(SBch,false,sizeof(SBch));
		//在这里进行初始化。 
		}else{
			int len=s.length();
			if(SBch[s[0]-'a'][s[len-1]-'a']==false){
			   SBch[s[0]-'a'][s[len-1]-'a']=true;
			   Sch [s[0]-'a'][Cch[s[0]-'a']++]=s[len-1];
			}
		/*这一步分就是记录字母表,它就是
		记录下每个字母所有能变化成的字母。*/
		}
	}
}
 

         我也是在看了很多博客后,都没有看到有用这种方法的。所以,就把我的方法放出来了,毕竟也算是祭奠经典题嘛!





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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值