您的位置:首页 > 大数据 > 人工智能

HUD ACM 1401 Solitaire (双向广搜+8进制状态压缩)

2013-01-19 15:38 183 查看
http://acm.hdu.edu.cn/showproblem.php?pid=1401

题意:给出4个点,问在一个8*8的方格中,能不能在8步以内由初始状态变换为目标状态

  输入有两行,分别表示初始状态和目标.

  每行有八个数字,两个数字为一组表示一个点的坐标

思路:由于点只在一个8*8的方格中移动,所以每一个坐标分别有8种状态,最大状态为88 = 16777216

  

#include <iostream>
#include <queue>
using namespace std;
struct Node{
int x;
int y;
};
struct Map{
Node node[4];
int step;
};
Map s;
Map e;
int Point[4][2] = {0,-1,0,1,-1,0,1,0};//上 下 左 右
int num[] = {1,8,64,512,4096,32768,262144,2097152};//表示每一位八进制数
char visit[20000000];//记录状态  用int会超内存
bool cmp(Node a,Node b){
if(a.x == b.x){
return a.y > b.y;
}
return a.x > b.x;
}
int Hash(Map p){//哈希算法,哈希后可以用一个整数表示一个图的状态
sort(p.node,p.node+4,cmp);//每次哈希前进行排序,判重
int sum = 0;
int i;
for(i=0;i<4;i++){
sum +=  p.node[i].x * num[i*2];
sum +=  p.node[i].y * num[i*2+1];
}
return sum;
}
//有相同 == 1 没有相同 == 0 越界 == -1
int Used(int x,int y,Map mid){
if(x >0 && x <= 8 && y > 0 && y <= 8){
int i;
for(i=0;i<4;i++){
if(mid.node[i].x == x && mid.node[i].y == y){
return 1;
}
}
return 0;
}
return -1;
}
int DoubleBFS(){//双向广搜即从初始状态和目标状态同时搜索,当搜索发现有重叠时表示能找到
queue <Map> q[2];
s.step = 0;
q[0].push(s);
int HashS = Hash(s);
int HashE = Hash(e);
if(HashS == HashE){
return 1;
}
visit[HashS] = 0;
while(!q[0].empty()){
Map mid= q[0].front();
q[0].pop();
if(mid.step >= 4){
break;
}
int i,j;
mid.step++;
for(i=0;i<4;i++){
for(j=0;j<4;j++){
int x,y;
x = mid.node[j].x + Point[i][0];
y = mid.node[j].y + Point[i][1];
if(Used(x,y,mid) == 1){
x +=Point[i][0];
y +=Point[i][1];
}
if(Used(x,y,mid) == 0){
Map flag = mid;
flag.node[j].x =  x;
flag.node[j].y =  y;
int result = Hash(flag);
if(visit[result] == -1){
visit[result] = 0;
q[0].push(flag);
}
}
}
}
}

if(visit[Hash(e)] == 0){
return 1;
}

e.step = 0;
q[1].push(e);
while(!q[1].empty()){
Map mid= q[1].front();
q[1].pop();
if(mid.step >= 4){
break;
}
int i,j;
mid.step++;
for(i=0;i<4;i++){
for(j=0;j<4;j++){
int x,y;
x = mid.node[j].x + Point[i][0];
y = mid.node[j].y + Point[i][1];
if(Used(x,y,mid) == 1){
x +=Point[i][0];
y +=Point[i][1];
}
if(Used(x,y,mid) == 0){
Map flag = mid;
flag.node[j].x =  x;
flag.node[j].y =  y;
int result = Hash(flag);
if(visit[result] == 0){
return 1;
}
else{
if(visit[result] == -1){
visit[result] = 1;
q[1].push(flag);
}
}
}
}
}
}
return 0;
}
int main(){
while(cin>>s.node[0].x>>s.node[0].y){
int i;
memset(visit,-1,sizeof(visit));
for(i=1;i<4;i++){
cin>>s.node[i].x>>s.node[i].y;
}
for(i=0;i<4;i++){
cin>>e.node[i].x>>e.node[i].y;
}
if(DoubleBFS()){
cout<<"YES"<<endl;
}
else{
cout<<"NO"<<endl;
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: