【宽搜】wikioi 1225 八数码难题

题目来源:http://wikioi.com/problem/1225/

分析:
宽搜+哈希

虽然用A*速度快,但编程繁琐而且容易出错。

宽搜较慢,但编程简单,思路清晰,而且此题数据范围不是很大,不会超时。

关于哈希,用stl中的map可以轻松解决。

具体做法:

对于每一个状态,、向不越界的方向扩展,将扩展出来的状态用hash判重,如果不重复,将新状态入队,同时将步数+1。

代码:

#include<iostream>
#include<algorithm>
#include<map>
#include<cstring>
#include<string>
using namespace std;
int head,tail,i,dang,gs,r2[182000],r3[182000];
string ccc,ch,r1[182000];
int main()
{ 
    map<string,int> hash;  //利用map实现哈希
    cin>>ch;
	for (i=0;i<ch.length();i++) if (ch[i]=='0') {dang=i; break;} 
	hash.insert(pair<string,int>(ch,1));
	r1[1]=ch;r2[1]=0;r3[1]=dang;
	head=1;tail=1;gs=1;
	while (head<=tail) 
	{
		string cc=r1[head],ccc;		
		if (r3[head]+1>=3)  //向上
		{
		   ccc=cc;
		   ccc[r3[head]]=ccc[r3[head]-3];
		   ccc[r3[head]-3]='0';
		   if (ccc=="123804765") 
		   {
		   	cout<<r2[head]+1;break;
		   }
		   else
		   if (hash.find(ccc)==hash.end())  //hsah判重
		    {
		      tail++;
			  gs++;	
		   	  hash.insert(pair<string,int>(ccc,gs));  
			  r2[tail]=r2[head]+1;    //新状态入队
		   	  r1[tail]=ccc;
		   	  r3[tail]=r3[head]-3;
	        }
		}
		if (r3[head]+1<=6)  //向下
		{
		   ccc=cc;
		   ccc[r3[head]]=ccc[r3[head]+3];
		   ccc[r3[head]+3]='0';
		   if (ccc=="123804765") 
		   {
		   	cout<<r2[head]+1;break;
		   }
		   else
		   if (hash.find(ccc)==hash.end())
		    {
		      tail++;
			  gs++;	
		   	  hash.insert(pair<string,int>(ccc,gs));
			  r2[tail]=r2[head]+1;
		   	  r1[tail]=ccc;
		   	  r3[tail]=r3[head]+3;
	        }
		}
		if ((r3[head]+1)%3!=0)  //向右
		{
		   ccc=cc;
		   ccc[r3[head]]=ccc[r3[head]+1];
		   ccc[r3[head]+1]='0';
		   if (ccc=="123804765") 
		   {
		   	cout<<r2[head]+1;break;
		   }
		   else
		   if (hash.find(ccc)==hash.end())
		    {
		      tail++;
			  gs++;	
		   	  hash.insert(pair<string,int>(ccc,gs));
			  r2[tail]=r2[head]+1;
		   	  r1[tail]=ccc;
		   	  r3[tail]=r3[head]+1;
	        }
		}
		if ((r3[head]+1)%3!=1)  //向左
		{
		   ccc=cc;
		   ccc[r3[head]]=ccc[r3[head]-1];
		   ccc[r3[head]-1]='0';
		   if (ccc=="123804765") 
		   {
		   	cout<<r2[head]+1;break;
		   }
		   else
		   if (hash.find(ccc)==hash.end())
		    {
		      tail++;
			  gs++;	
		   	  hash.insert(pair<string,int>(ccc,gs));
			  r2[tail]=r2[head]+1;
		   	  r1[tail]=ccc;
		   	  r3[tail]=r3[head]-1;
	        }
		}
		head++;
	}
  return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值