您的位置:首页 > 其它

UVA 1343 - The Rotation Game-[IDA*迭代加深搜索]

2016-04-01 01:22 561 查看

解题思路:

  这是紫书上的一道题,一开始笔者按照书上的思路采用状态空间搜索,想了很多办法优化可是仍然超时,时间消耗大的原因是主要是:

    1)状态转移代价很大,一次需要向八个方向寻找;

    2)哈希表更新频繁;

    3)采用广度优先搜索结点数越来越多,耗时过大;

  经过简单计算,最长大概10次左右的变换就能出解,于是笔者就尝试采用IDA*,迭代加深搜索的好处是:

    1)无需存储状态,节约时间和空间;

    2)深度优先搜索查找的结点数少;

    3)递归方便剪枝;

代码如下:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <ctime>

using namespace std;
8
#define time_ printf("time :%f\n",double(clock())/CLOCKS_PER_SEC)
#define maxs 735471
typedef int state[24];
int init_p[24];
state start;
int num;
int seq[maxs];
int cur;
char P1[maxs];
int maxd;
inline void get_P(char *P){
for(int i=0;i<cur;i++)
P[i]=seq[i]+'A';
}
int pos[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 tar[8]={6,7,8,11,12,15,16,17};

inline int tar_num(const state &p){
int cnt=0;
for(int k=1;k<=3;k++){
int c=0;
for(int i=0;i<8;i++)
if(p[tar[i]]==k)
c++;
cnt=max(c,cnt);
}
return cnt;
}
inline void move(state& s,int i){
int temp=s[pos[i][0]];
int j=0;
for(;j<6;j++)
s[pos[i][j]]=s[pos[i][j+1]];
s[pos[i][j]]=temp;
}
bool dfs(state& u,int s_d){
if(s_d==maxd){
if(tar_num(u)==8){
num=u[tar[0]];
return true;
}
return false;
}
if(8-tar_num(u)>maxd-s_d)
return false;
for(int i=0;i<8;i++){
move(u,i);
seq[cur++]=i;
if(dfs(u,s_d+1))
return true;
cur--;
if(i%2) move(u,(i+3)%8);
else move(u,(i+5)%8);
}
return false;
}
inline void init(){
memset(seq, -1, sizeof seq);
cur=0;
}
bool solve(){
init();
bool ok=false;
state u;
memcpy(u, init_p, sizeof u);
if(tar_num(u)==8){
printf("‘No moves needed\n");
}
if(dfs(u,0)){
ok=true;
get_P(P1);
}
return ok;
}
int main() {

while(1){
memset(P1, 0, sizeof P1);
for(int i=0;i<24;i++){
scanf("%d",&init_p[i]);
if(init_p[i]==0) {
//time_;
return 0;
}
}
state u;
memcpy(u, init_p, sizeof u);
if(tar_num(u)==8){
printf("No moves needed\n%d\n",u[tar[0]]);
continue;
}
for(maxd=1;;maxd++)
if(solve())
break;
printf("%s\n%d\n",P1,num);
//time_;
}
return 0;
}

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: