POJ 2286 The Rotation Game IDA*

这个题用IDA*算法比较好,代码量也比A*小,空间消耗也小。

估价函数也比较好找,就是中间8个方格距离这8个方格同数的最短距离。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int init[30];
int sol[1010];
int bound;
bool ans;
int final;
int e[8]={6,7,8,11,12,15,16,17};
int re[8]={5,4,7,6,1,0,3,2};
int cha[4][7]={0,2,6,11,15,20,22,
			   1,3,8,12,17,21,23,
			   10,9,8,7,6,5,4,
			   19,18,17,16,15,14,13};
int Max(int a,int b){
	return a>b?a:b;
}
int Min(int a,int b){
	return a<b?a:b;
}
int h(int *a){
	int i;
	int b=0,c=0,d=0;
	for(i=0;i<8;i++){
		if(a[e[i]]==1)
			b++;
		else if(a[e[i]]==2)
			c++;
		else if(a[e[i]]==3)
			d++;
	}
	return 8-Max(b,Max(c,d));
}
void change(int dir,int * tmp){
	int i;
	if(dir<4){
		int temp=tmp[cha[dir][0]];
		for(i=1;i<7;i++)
			tmp[cha[dir][i-1]]=tmp[cha[dir][i]];
		tmp[cha[dir][6]]=temp;
	}
	else{
		int temp=tmp[cha[re[dir]][6]];
		for(i=6;i>0;i--)
			tmp[cha[re[dir]][i]]=tmp[cha[re[dir]][i-1]];
		tmp[cha[re[dir]][0]]=temp;
	}
}
int dfs(int * a,int depth,int premove){
	int hdepth,i,j;
	hdepth=h(a);
	if(hdepth+depth>bound)
		return hdepth+depth;
	if(hdepth==0){
		ans=true;
		final=a[6];
		return depth;
	}
	int next_bound=1e7;
	for(i=0;i<8;i++){
		if(re[i]==premove)
			continue;
		int tmp[30];
		for(j=0;j<24;j++)
			tmp[j]=a[j];
		change(i,tmp);
		sol[depth]=i;
		int new_bound=dfs(tmp,depth+1,i);
		if(ans)
			return new_bound;
		else
			next_bound=Min(new_bound,next_bound);
	}
	return next_bound;
}
void IDA_STAR(){
	memset(sol,0,sizeof(sol));
	bound=h(init);
	ans=false;
	while(!ans && bound<=100){
		bound=dfs(init,0,-100);
	}
	for(int i=0;i<bound;i++)
		printf("%c",sol[i]+'A');
	printf("\n");
	printf("%d\n",final);
}
int main(){
	int i,j;
	while(scanf("%d",&init[0]) && init[0]!=0){
		for(i=1;i<24;i++)
			scanf("%d",&init[i]);
		if(h(init)==0){
			printf("No moves needed\n");
			printf("%d\n",init[6]);
			continue;
		}
		IDA_STAR();
	}
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值