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

http://acm.hdu.edu.cn/showproblem.php?pid=1401

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

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

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

 

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

  

  1 #include <iostream>
  2  #include <queue>
  3  using namespace std;
  4  struct Node{
  5      int x;
  6      int y;
  7  };
  8  struct Map{
  9      Node node[4];
 10      int step;
 11  };
 12  Map s;
 13  Map e;
 14  int Point[4][2] = {0,-1,0,1,-1,0,1,0};//上 下 左 右
 15  int num[] = {1,8,64,512,4096,32768,262144,2097152};//表示每一位八进制数
 16  char visit[20000000];//记录状态  用int会超内存
 17  bool cmp(Node a,Node b){
 18      if(a.x == b.x){
 19          return a.y > b.y;
 20      }
 21      return a.x > b.x;
 22  }
 23  int Hash(Map p){//哈希算法,哈希后可以用一个整数表示一个图的状态
 24      sort(p.node,p.node+4,cmp);//每次哈希前进行排序,判重
 25      int sum = 0;
 26      int i;
 27      for(i=0;i<4;i++){
 28          sum +=  p.node[i].x * num[i*2];
 29          sum +=  p.node[i].y * num[i*2+1];
 30      }
 31      return sum;
 32  }
 33  //有相同 == 1 没有相同 == 0 越界 == -1
 34  int Used(int x,int y,Map mid){
 35      if(x >0 && x <= 8 && y > 0 && y <= 8){
 36          int i;
 37          for(i=0;i<4;i++){
 38              if(mid.node[i].x == x && mid.node[i].y == y){
 39                  return 1;
 40              }
 41          }
 42          return 0;
 43      }
 44      return -1;
 45  }
 46  int DoubleBFS(){//双向广搜即从初始状态和目标状态同时搜索,当搜索发现有重叠时表示能找到
 47      queue <Map> q[2];
 48      s.step = 0;
 49      q[0].push(s);
 50      int HashS = Hash(s);
 51      int HashE = Hash(e);
 52      if(HashS == HashE){
 53          return 1;
 54      }
 55      visit[HashS] = 0;
 56      while(!q[0].empty()){
 57          Map mid= q[0].front();
 58          q[0].pop();
 59          if(mid.step >= 4){
 60              break;
 61          }
 62          int i,j;
 63          mid.step++;
 64          for(i=0;i<4;i++){
 65              for(j=0;j<4;j++){
 66                  int x,y;
 67                  x = mid.node[j].x + Point[i][0];
 68                  y = mid.node[j].y + Point[i][1];
 69                  if(Used(x,y,mid) == 1){
 70                      x +=Point[i][0];
 71                      y +=Point[i][1];
 72                  }
 73                  if(Used(x,y,mid) == 0){
 74                      Map flag = mid;
 75                      flag.node[j].x =  x;
 76                      flag.node[j].y =  y;
 77                      int result = Hash(flag);
 78                      if(visit[result] == -1){
 79                          visit[result] = 0;
 80                          q[0].push(flag);
 81                      }
 82                  }
 83              }
 84          }
 85      }
 86  
 87      if(visit[Hash(e)] == 0){
 88          return 1;
 89      }
 90  
 91      e.step = 0;
 92      q[1].push(e);
 93      while(!q[1].empty()){
 94          Map mid= q[1].front();
 95          q[1].pop();
 96          if(mid.step >= 4){
 97              break;
 98          }
 99          int i,j;
100          mid.step++;
101          for(i=0;i<4;i++){
102              for(j=0;j<4;j++){
103                  int x,y;
104                  x = mid.node[j].x + Point[i][0];
105                  y = mid.node[j].y + Point[i][1];
106                  if(Used(x,y,mid) == 1){
107                      x +=Point[i][0];
108                      y +=Point[i][1];
109                  }
110                  if(Used(x,y,mid) == 0){
111                      Map flag = mid;
112                      flag.node[j].x =  x;
113                      flag.node[j].y =  y;
114                      int result = Hash(flag);
115                      if(visit[result] == 0){
116                          return 1;
117                      }
118                      else{
119                          if(visit[result] == -1){
120                              visit[result] = 1;
121                              q[1].push(flag);
122                          }
123                      }
124                  }
125              }
126          }
127      }
128      return 0;
129  }
130  int main(){
131      while(cin>>s.node[0].x>>s.node[0].y){
132          int i;
133          memset(visit,-1,sizeof(visit));
134          for(i=1;i<4;i++){
135              cin>>s.node[i].x>>s.node[i].y;
136          }
137          for(i=0;i<4;i++){
138              cin>>e.node[i].x>>e.node[i].y;
139          }
140          if(DoubleBFS()){
141              cout<<"YES"<<endl;
142          }
143          else{
144              cout<<"NO"<<endl;
145          }
146      }
147  }

 

 

posted @ 2013-01-19 15:38  zx雄  阅读(701)  评论(0编辑  收藏  举报