您的位置:首页 > 其它

POJ-2286 The Rotation Game IDA*

2013-04-30 22:10 447 查看
  题目链接:http://poj.org/problem?id=2286

  IDA*对于最优解层数小,每次扩展状态多的时候是一个杀手锏啊。IDA*就是一个加了层数限制depth的DFS,超过了限制就不在搜索下去,如果在当前层数没有搜到目标状态,就加大层数限制depth,这里还只是一个IDA算法,并不是A*的。当然我们可以用A*的估计函数去剪枝,如果当前深度d+h()>depth的时候就可以不再搜索下去了,这样就是IDA*了。

  对于这道题,我们把状态用一维数组存储,然后对每个元素设定相应的编号:

           0     1
          2     3
      4  5  6  7  8  9  10
            11    12
      13 14 15 16 17 18 19
           20    21
           22    23

  并且把每个操作的相应编号用数组存起来就好处理了:

//STATUS:C++_AC_313MS_168KB
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<iostream>
#include<string>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
using namespace std;
//define
#define pii pair<int,int>
#define mem(a,b) memset(a,b,sizeof(a))
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define PI acos(-1.0)
//typedef
typedef long long LL;
typedef unsigned long long ULL;
//const
const int N=210;
const int INF=0x3f3f3f3f;
const int MOD=1000007,STA=400010;
const LL LNF=1LL<<60;
const double EPS=1e-8;
const double OO=1e15;
const int dx[4]={-1,0,1,0};
const int dy[4]={0,1,0,-1};
//Daily Use ...
template<class T> inline T Min(T a,T b){return a<b?a:b;}
template<class T> inline T Max(T a,T b){return a>b?a:b;}
template<class T> inline T Min(T a,T b,T c){return min(min(a, b),c);}
template<class T> inline T Max(T a,T b,T c){return max(max(a, b),c);}
//End

char op[]="ABCDEFGH";
int ma[8][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,
23,21,17,12,8,3,1,
22,20,15,11,6,2,0,
13,14,15,16,17,18,19,
4,5,6,7,8,9,10,
};
int r[]={5,4,7,6,1,0,3,2};
int mid[]={6,7,8,11,12,15,16,17};
int path
,s[24];
int depth;

int geth(int s[])
{
int i,cnt[]={0,0,0,0};
for(i=0;i<8;i++){
cnt[s[mid[i]]]++;
}
return 8-Max(cnt[1],cnt[2],cnt[3]);
}

void move(int op)
{
int i,t;
t=s[ma[op][0]];
for(i=1;i<7;i++){
s[ma[op][i-1]]=s[ma[op][i]];
}
s[ma[op][6]]=t;
}

int idastar(int d)
{
if(d>=depth)return 0;
int i,h;
for(i=0;i<8;i++){
move(i);
path[d]=i;
h=geth(s);
if(!h)return 1;
if(d+h<depth && idastar(d+1))return 1;
move(r[i]);
}
return 0;
}

int main()
{
//   freopen("in.txt","r",stdin);
int i;
while(~scanf("%d",&s[0]) && s[0])
{
for(i=1;i<24;i++)
scanf("%d",&s[i]);
depth=geth(s);
if(!depth){
printf("No moves needed\n%d\n",s[mid[0]]);
}
else {
while(!idastar(0))depth++;
for(i=0;i<depth;i++){
printf("%c",op[path[i]]);
}
printf("\n%d\n",s[mid[0]]);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: