您的位置:首页 > 其它

搜索 POJ 3131 Cubic Eight-Puzzle

2016-09-03 20:57 387 查看
题目链接:POJ 3131 Cubic Eight-Puzzle

分析:

总是讨论空格,一共有四种可能,上下左右的方块可以滚过来。

对于一个格子,用pair记录两个值,xx表示上面的颜色,yy表示前面的颜色。

1=白色,2=红色,3=蓝色。

如果前后滚动,xx,yy交换。

如果左右滚动, yy不变,xx变成除了xx,yy之外的那一种颜色。

剪枝1: 记下上一层的空格在哪里,不要滚回去。

剪枝2: 最优化剪枝,看当前有几个格子和目标不一样,如果加上当前步数超过当前答案,则剪枝。

就这样水水的剪一剪就A了。

代码如下:

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<queue>
#include<vector>
#include<algorithm>

#define xx first
#define yy second
#define LL long long
#define CLEAR(xxx) memset(xxx,0,sizeof(xxx))
#define INTpair pair<int,int>

using namespace std;
const int maxn=5,n=3,inf=32;

int ans,t[maxn][maxn];
INTpair s[maxn][maxn];
int dx[4]={-1,1,0,0},dy[4]={0,0,-1,1};

int Best(){
int ans=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(s[i][j].xx!=t[i][j]) ans++;
return ans;
}

void move(int x,int y,int type){
int x1=x+dx[type],y1=y+dy[type];
if(type<2)
swap(s[x][y].xx,s[x][y].yy);
else
s[x][y].xx=1^2^3^s[x][y].xx^s[x][y].yy;
swap(s[x][y],s[x1][y1]);
}

void DFS(int dep,int x,int y){
//x,y,是记录上一次的空格
int i,j,h=Best();
if(h==0){
ans=min(ans,dep);
return ;
}
if(dep+h>=ans) return ;
int x1,y1;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
if(!s[i][j].xx)x1=i,y1=j;
//x1,t=y1,是现在空格的位置
for(i=0;i<4;i++){
int tx=dx[i]+x1,ty=dy[i]+y1;
if(tx>0&&tx<=n&&ty>0&&ty<=n&&(tx!=x||ty!=y)){
move(tx,ty,i^1);
DFS(dep+1,x1,y1);
move(x1,y1,i);
}
}
}

int main(){
int i,j,x,y;
char ch;
while(cin>>y>>x){
if(!y&&!x) return 0;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)s[i][j]=make_pair(1,2);
s[x][y]=make_pair(0,0);
for(i=1;i<=n;i++)
for(j=1;j<=n;j++){
cin>>ch;
if(ch=='E')t[i][j]=0;
else if(ch=='W')t[i][j]=1;
else if(ch=='R')t[i][j]=2;
else t[i][j]=3;
}
ans=inf;
DFS(0,0,0);
if(ans>30) ans=-1;
cout<<ans<<endl;
}
return 0;
}

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