转载请注明出处,谢谢 http://blog.csdn.net/ACM_cxlove?viewmode=contents by---cxlove
第一个IDA*搜索。
迭代加深搜索是逐渐加深搜深度,和BFS比较,不需要大量内存存取状态,但是耗时增加,因为好多都是重复搜索。
因为迭代加深搜索适用于对内存要求高,但是对时限要求不太高的题目。
而IDA*就是在在迭代加深搜索中加入估价函数,就是DFS中的剪枝。
对于这题来说算不上IDA*,就是迭代深搜加了个剪枝。
由于 每做一步,8个位置只变了一个,估价函数就是至少有几个位置不满足。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#include<cmath>
#include<map>
#include<string>
#define inf 1<<30
#define eps 1e-7
#define LD long double
#define LL long long
#define maxn 1005
using namespace std;
int central[8]={6,7,8,11,12,15,16,17}; //中间8个方格的位置
int rotation[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}};//分别是每7个按顺序列好
int to[8]={0,1,2,3,1,0,3,2}; //8种转换分别对应于哪7个方块
int rev[8]={5,4,7,6,1,0,3,2}; //每一种转换的相反转换是哪个
int ope[maxn]; //存储转换操作
int a[24]; //原始序列
bool flag; //是否有解
int depth; //当前搜索深度
int get_h(int *m){ //得到估价函数h
int a=0,b=0,c=0;
for(int i=0;i<8;i++)
if(m[central[i]]==1)
a++;
else if(m[central[i]]==2)
b++;
else if(m[central[i]]==3)
c++;
return 8-max(a,max(b,c));
}
void change(int *b,int kind){
if(kind<4){
int tmp=b[rotation[to[kind]][0]];
for(int i=0;i<6;i++)
b[rotation[to[kind]][i]]=b[rotation[to[kind]][i+1]];
b[rotation[to[kind]][6]]=tmp;
}
else{
int tmp=b[rotation[to[kind]][6]];
for(int i=6;i>0;i--)
b[rotation[to[kind]][i]]=b[rotation[to[kind]][i-1]];
b[rotation[to[kind]][0]]=tmp;
}
}
void IDAstar(int *b,int tmp_depth,int father){ //当前序列,当前深度,父节点
if(get_h(b)>tmp_depth) //这就是利用估价函数的剪枝,h的值表示至少还需要多少步,如果在当前深度完成不了就剪掉
return;
if(flag) //如果已经有解就退出
return;
if(tmp_depth==0&&get_h(b)==0){ //深度为0,且为目标状态
flag=true;
for(int j=depth;j>0;j--)
printf("%c",ope[j]+'A');
printf("\n%d\n",b[6]);
return;
}
for(int i=0;i<8;i++){
int tmp[24];
if(rev[i]==father) //避免死循环,相反操作两次则抵消
continue;
for(int i=0;i<24;i++)
tmp[i]=b[i];
change(tmp,i);
ope[tmp_depth]=i;
dfs(tmp,tmp_depth-1,i);
}
}
int main(){
while(scanf("%d",&a[0])!=EOF&&a[0]){
for(int i=1;i<24;i++)
scanf("%d",&a[i]);
if(get_h(a)==0){
printf("No moves needed\n%d\n",a[6]); //wa两次,不需要操作也需要输出中心数字
continue;
}
flag=false;
for(depth=get_h(a);;depth++){ //迭代加深,至少需要h(a)步,很好理解
dfs(a,depth,-1);
if(flag) //有解则退出
break;
}
}
return 0;
}