2016夏季练习——搜索

本文介绍了一种基于IDA*搜索算法解决拼图问题的方法。通过详细的代码示例,展示了如何利用IDA*算法进行有效搜索,并解决了特定的拼图问题。文章提供了完整的C++代码实现,包括状态转移、启发式评估函数等关键部分。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

来源:HDU1667

IDA*

四个小时的debug,搞完了好激动啊

中间的东西写烦了

代码:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
int a[25];
int s[4][8];
int mp[3][3];
int maxdep;
int flag;
char ans[10010];
int pre[10];
void debug(){
	for(int i=0;i<3;i++){
		for(int j=0;j<3;j++){
			cout<<mp[i][j]<<" ";
		}
		cout<<endl;
	}
}
int duiying(int n)
{
	if(n==0) return 5;
	if(n==1) return 4;
	if(n==2) return 7;
	if(n==3) return 6;
	if(n==4) return 1;
	if(n==5) return 0;
	if(n==6) return 3;
	if(n==7) return 2;
}
void getmp(){
	memset(mp,0,sizeof(mp));
	mp[0][0]=s[0][2];mp[0][1]=s[0][3];mp[0][2]=s[0][4];
	mp[1][0]=s[2][3];mp[1][1]    =  0;mp[1][2]=s[3][3];
	mp[2][0]=s[1][2];mp[2][1]=s[1][3];mp[2][2]=s[1][4];
}
void ini(){
	//s1
	s[0][0]=a[4];
	s[0][1]=a[5];
	s[0][2]=a[6];
	s[0][3]=a[7];
	s[0][4]=a[8];
	s[0][5]=a[9];
	s[0][6]=a[10];
	//s2
	s[1][0]=a[13];
	s[1][1]=a[14];
	s[1][2]=a[15];
	s[1][3]=a[16];
	s[1][4]=a[17];
	s[1][5]=a[18];
	s[1][6]=a[19];
	//s3
	s[2][0]=a[0];
	s[2][1]=a[2];
	s[2][2]=a[6];
	s[2][3]=a[11];
	s[2][4]=a[15];
	s[2][5]=a[20];
	s[2][6]=a[22];
	//s4;
	s[3][0]=a[1];
	s[3][1]=a[3];
	s[3][2]=a[8];
	s[3][3]=a[12];
	s[3][4]=a[17];
	s[3][5]=a[21];
	s[3][6]=a[23];
	/*for(int i=0;i<4;i++){
		for(int j=0;j<7;j++){
			cout<<s[i][j]<<" ";
		}
		cout<<endl;
	}*/
	getmp();
}
int judge(){
	int cnt1,cnt2,cnt3;
	cnt1=cnt2=cnt3=0;
	for(int i=0;i<3;i++){
		for(int j=0;j<3;j++){
			if(mp[i][j]){
				if(mp[i][j]==1) cnt1++;
				if(mp[i][j]==2) cnt2++;
				if(mp[i][j]==3) cnt3++;
 			}
		}
	}
	int maxn=cnt1;
	if(maxn<cnt2){
		maxn=cnt2;
	}
	if(maxn<cnt3){
		maxn=cnt3;
	}
	return 8-maxn;
}
//
void funA(){
	int d=s[2][0];
	for(int i=1;i<7;i++){
		s[2][i-1]=s[2][i];
	}
	s[2][6]=d;
	s[0][2]=s[2][2];
	s[1][2]=s[2][4];
	getmp();
}
void funB(){
	int d=s[3][0];
	for(int i=1;i<7;i++){
		s[3][i-1]=s[3][i];
	}
	s[3][6]=d;
	s[0][4]=s[3][2];
	s[1][4]=s[3][4];
	getmp();
}
void funC(){
	int d=s[0][6];
	for(int i=6;i>=1;i--){
		s[0][i]=s[0][i-1];
	}
	s[0][0]=d;
	s[2][2]=s[0][2];
	s[3][2]=s[0][4];
	getmp();
}
void funD(){
	int d=s[1][6];
	for(int i=6;i>=1;i--){
		s[1][i]=s[1][i-1];
	}
	s[1][0]=d;
	s[2][4]=s[1][2];
	s[3][4]=s[1][4];
	getmp();
}
void funE(){
	int d=s[3][6];
	for(int i=6;i>=1;i--){
		s[3][i]=s[3][i-1];
	}
	s[3][0]=d;
	s[0][4]=s[3][2];
	s[1][4]=s[3][4];
	getmp();
}
void funF(){
	int d=s[2][6];
	for(int i=6;i>=1;i--){
		s[2][i]=s[2][i-1];
	}
	s[2][0]=d;
	s[0][2]=s[2][2];
	s[1][2]=s[2][4];
	getmp();
}
void funG(){
	int d=s[1][0];
	for(int i=1;i<7;i++){
		s[1][i-1]=s[1][i];
	}
	s[1][6]=d;
	s[2][4]=s[1][2];
	s[3][4]=s[1][4];
	getmp();
}
void funH(){
	int d=s[0][0];
	for(int i=1;i<7;i++){
		s[0][i-1]=s[0][i];
	}
	s[0][6]=d;
	s[2][2]=s[0][2];
	s[3][2]=s[0][4];
	getmp();
}
//
void move(int kind){
	switch(kind){
		case 0:funA();break;
		case 1:funB();break;
		case 2:funC();break;
		case 3:funD();break;
		case 4:funE();break;
		case 5:funF();break;
		case 6:funG();break;
		case 7:funH();break;
	}
}
/*

*/
void relay(int kind){
	switch(kind){
		case 0:funF();break;
		case 1:funE();break;
		case 2:funH();break;
		case 3:funG();break;
		case 4:funB();break;
		case 5:funA();break;
		case 6:funD();break;
		case 7:funC();break;
	}
}
void IDA_Star(int floor,int pre){
	if(judge()+floor>maxdep) return ;
	if(flag) return ;
	if(floor==maxdep&&judge()==0){
		flag=mp[0][0];
		return ;
	}
	/*cout<<floor<<" "<<(char)(pre+'A')<<": "<<endl;
	debug();*/
	for(int i=0;i<8;i++){
		if(i==duiying(pre)) continue;
		move(i);
		ans[floor]=i+'A';
		IDA_Star(floor+1,i);
		relay(i);
		if(flag) return ;
	}
}
void print(){
	for(int i=0;i<maxdep;i++){
		cout<<ans[i];
	}
	cout<<endl<<flag<<endl;
}
int main(){
	int d;
	while(scanf("%d",&d)!=EOF&&d){
		a[0]=d;
		for(int i=1;i<24;i++){
			scanf("%d",a+i);
		}
		ini();
		memset(ans,0,sizeof(ans));
		maxdep=0;
		if(judge()==0) {
			cout<<"No moves needed"<<endl;
			cout<<mp[0][0]<<endl;
			continue;
		}
		//debug();
		flag=0;
		for(maxdep=judge();;maxdep++){
			//cout<<"maxdep: "<<maxdep<<": "<<endl;
			IDA_Star(0,-1);
			if(flag) break;
		}
		print();
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值