2016夏季练习——搜索

来源:HDU1043

A*

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
#include <string>
#include <cmath>
#include <vector>
using namespace std;
///define
struct Node{
	int maze[3][3];
	int h,g;
	int x,y;
	int Hash;
	bool operator<(const Node x)const{
		return h!=x.h?(h>x.h):(g>x.g);
	}
	bool check(){
		if(x>=0&&x<3&&y>=0&&y<3)
			return true;
		return false;
	}
};
const int Des=322560;
Node s,u,v,tt;
char ch[40];
int ccc[9]={1,1,2,6,24,120,720,5040,40320};
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
char str[5]={'r','l','d','u'};
int vis[400000];
int pre[400000];

///function area
//ini hash
int hashfun(Node tmp){
	int a[9];
	int k=0;
	for(int i=0;i<3;i++){
		for(int j=0;j<3;j++){
			a[k++]=tmp.maze[i][j];
		}
	}
	int ans=0;
	for(int i=0;i<9;i++){
		int k=0;
		for(int j=0;j<i;j++){
			if(a[j]>a[i])
				k++;
		}
		ans+=(ccc[i]*k);
	}
	return ans;
}
//cantor
int cantor(int a[]){
	int cnt;
	int ans=0;
	for(int i=0;i<9;i++){
		cnt=1;
		for(int j=i+1;j<9;j++){
			if(a[i]>a[j]) cnt++;
		}
		ans=ans+cnt*ccc[9-i];
	}
	return ans;
}
//nixushupanduan
bool isok(Node tmp){
	int a[9];
	int k=0;
	for(int i=0;i<3;i++){
		for(int j=0;j<3;j++){
			a[k++]=tmp.maze[i][j];
		}
	}
	int cnt=0;
	for(int i=0;i<9;i++){
		for(int j=i+1;j<9;j++){
			if(a[i]>a[j]&&a[j]&&a[i]) cnt++;
		}
	}
	return !(cnt&1);
}
//mahatun
int tohash(Node tmp){
	int ans=0;
	for(int i=0;i<3;i++){
		for(int j=0;j<3;j++){
			if(tmp.maze[i][j])
				ans+=abs(i-(tmp.maze[i][j]-1)/3)+abs(j-(tmp.maze[i][j]-1)%3);
		}
	}
	return ans;
}

//Astar
void A_Star(){
	priority_queue<Node>Q;
	Q.push(s);
	while(!Q.empty()){
		u=Q.top();
		//cout<<u.Hash<<endl;
		Q.pop();
		for(int i=0;i<4;i++){
			v=u;
			v.x+=dx[i];
			v.y+=dy[i];
			if(v.check()){
				//cout<<"ans"<<endl;
				swap(v.maze[v.x][v.y],v.maze[u.x][u.y]);
				v.Hash=hashfun(v);
				if(vis[v.Hash]==-1&&isok(v)){
					vis[v.Hash]=i;
					v.g++;
					pre[v.Hash]=u.Hash;
					v.h=tohash(v);
					Q.push(v);
				}
				if(v.Hash==Des){
					//cout<<"k"<<endl;
					return ;
				}
			}
		}
	}
}

//print
void print(){
	//cout<<"ddd"<<endl;
	string ans;
	ans.clear();
	//cout<<"dsadfs"<<endl;
	int nxt=Des;
	//cout<<pre[nxt]<<endl;
	while(pre[nxt]!=-1){
		switch(vis[nxt]){
			case 0:ans+='r';break;
			case 1:ans+='l';break;
			case 2:ans+='d';break;
			case 3:ans+='u';break;
		}
		//cout<<"dffff"<<endl;
		nxt=pre[nxt];
	}
	//cout<<"a"<<endl;
	for(int i=ans.size()-1;i>=0;i--){
		putchar(ans[i]);
	}
	cout<<endl;
}
int main(){
	gets(ch);
	memset(pre,-1,sizeof(pre));
	memset(vis,-1,sizeof(vis));
	int k=0;
	for(int i=0;i<3;i++){
		for(int j=0;j<3;j++){
			if((ch[k]<='9'&&ch[k]>='0')||ch[k]=='x'){
				if(ch[k]=='x'){
					s.maze[i][j]=0;
					s.x=i;
					s.y=j;
				}
				else{
					s.maze[i][j]=ch[k]-'0';
				}
			}
			else
				j--;
			k++;
		}
	}
	/*
	for(int i=0;i<9;i++)
		cout<<data[i]<<" ";
	cout<<endl;
	*/
	//cout<<"d1"<<endl;
	if(!isok(s)) {
		cout<<"unsolvable"<<endl;
		return 0;
	}
	//cout<<"d2"<<endl;
	s.Hash=hashfun(s);
	//cout<<"d3"<<endl;
	if(s.Hash==Des){
		cout<<endl;
		return 0;
	}
	vis[s.Hash]=-2;
	s.g=0;
	s.h=tohash(s);
	//cout<<"d4"<<endl;
	A_Star();
	//cout<<"d5"<<endl;
	print();
	return 0;
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值