首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

HDU 1667 The Rotation Game IDA*搜寻

2012-08-17 
HDU 1667 The Rotation Game IDA*搜索转载请注明出处,谢谢 http://blog.csdn.net/ACM_cxlove?viewmodecon

HDU 1667 The Rotation Game IDA*搜索

转载请注明出处,谢谢 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 1005using 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){   //得到估价函数hint 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;}


 

热点排行