poj 1198 / hdu 1401 Solitaire (记忆化搜索+meet in middle)

题目大意:给你一个8*8的棋盘,上面有四个棋子,给你一个初始排布,一个目标排布,每次移动,可以把一个棋子移动到一个相邻的空位,或者跨过1个相邻的棋子,在保证棋子移动不超过8次的情况下,问能否把棋盘上的棋子由初始排布变成目标排布

8*8的棋盘,刚好不爆ull,状压那些位置有棋子

然后从初始状态开始,暴搜出当前状态下,移动一个棋子之后所有可能到达的状态

直接搜,总状态数是8^8,此外还有常数,会爆

由于给定了目标排布,考虑meet in middle

从起始状态和目标状态各搜4步即可

为了防止爆栈,同时为了好写好调,最好用bfs

具体实现呢,可以开两个队列正反同时bfs,搜到合法结果就break掉,可以减少很多常数

开2个map,表示正/反着跑能否到达状态s,如果能到达,则mp[s]=1

以正着搜为例,当前从que1中取出的状态为s,能到达的下一个状态为t,如果t出现在map1中,就不必在推入que1了,如果t出现在map2中,说明存在合法状态,break掉输出YES

代码好长啊..但在搜索题里算短的了

扫描二维码关注公众号,回复: 4188169 查看本文章
  1 #include <map>
  2 #include <queue>
  3 #include <cstdio>
  4 #include <cstring>
  5 #include <algorithm>
  6 #define NN 5010
  7 #define MM 2000
  8 #define maxn 200
  9 #define ll long long 
 10 #define uint unsigned int
 11 #define ull unsigned long long 
 12 using namespace std;
 13 
 14 int id[10][10];
 15 int xx[4]={-1,0,1,0};
 16 int yy[4]={0,1,0,-1};
 17 ull bin[100];
 18 int ax[5],ay[5],bx[5],by[5];
 19 struct node{
 20     ull s;int c;
 21     friend bool operator < (const node &s1,const node &s2)
 22         {return s1.s<s2.s;}
 23     node(ull s,int c):s(s),c(c){}
 24     node(){}
 25 };
 26 map<ull,int>mp[2];
 27 int check(int x,int y,ull s)
 28 {
 29     if(x<1||y<1||x>8||y>8)return 0;
 30     if(s&bin[id[x][y]]) return 2;
 31     return 1;
 32 }
 33 
 34 int main()
 35 {
 36     //freopen("t2.in","r",stdin);
 37     for(int i=1;i<=8;i++)
 38         for(int j=1;j<=8;j++)
 39             id[i][j]=8*(i-1)+j-1;
 40             //px[id[i][j]]=i,py[id[i][j]]=j;
 41     bin[0]=1;
 42     for(int i=1;i<=63;i++)
 43         bin[i]=bin[i-1]<<1;
 44     while(scanf("%d%d%d%d",&ax[1],&ay[1],&ax[2],&ay[2])!=EOF)
 45     {
 46     scanf("%d%d%d%d",&ax[3],&ay[3],&ax[4],&ay[4]);
 47     scanf("%d%d%d%d",&bx[1],&by[1],&bx[2],&by[2]);
 48     scanf("%d%d%d%d",&bx[3],&by[3],&bx[4],&by[4]);
 49     queue<node>q[2];
 50     ull s=0,t=0;
 51     int cnt=0,fx,fy,fl,nt;
 52     for(int i=1;i<=4;i++)
 53         s|=bin[id[ax[i]][ay[i]]];
 54     mp[0][s]=1;
 55     q[0].push(node(s,0));s=0;
 56     for(int i=1;i<=4;i++)
 57         s|=bin[id[bx[i]][by[i]]];
 58     mp[1][s]=1;
 59     q[1].push(node(s,0));
 60     int ans=0,c,x,y;
 61     while((!q[0].empty()||!q[1].empty())&&!ans)
 62     {
 63         if(!q[0].empty())
 64         {
 65         node K=q[0].front();q[0].pop();
 66         s=K.s,c=K.c;
 67         for(int i=1;i<=8;i++)
 68         for(int j=1;j<=8;j++)
 69         {
 70             if(!(s&bin[id[i][j]])) continue;
 71             for(int k=0;k<4;k++)
 72             {
 73                 x=i+xx[k],y=j+yy[k];
 74                 fl=check(x,y,s);
 75                 if(!fl) continue;
 76                 if(fl==2){
 77                     x+=xx[k],y+=yy[k];
 78                     if(check(x,y,s)!=1) continue;
 79                 }
 80                 t=(s^bin[id[i][j]])|bin[id[x][y]];
 81                 if(mp[0].find(t)!=mp[0].end())
 82                     continue;
 83                 if(mp[1].find(t)!=mp[1].end())
 84                     {ans=1;break;}
 85                 mp[0][t]=1;
 86                 if(c<3) q[0].push(node(t,c+1));
 87                 if(ans==1) break;
 88             }
 89         }
 90         }
 91         if(!q[1].empty())
 92         {
 93         node K=q[1].front();q[1].pop();
 94         s=K.s,c=K.c;
 95         for(int i=1;i<=8;i++)
 96         for(int j=1;j<=8;j++)
 97         {
 98             if(!(s&bin[id[i][j]])) continue;
 99             for(int k=0;k<4;k++)
100             {
101                 x=i+xx[k],y=j+yy[k];
102                 fl=check(x,y,s);
103                 if(!fl) continue;
104                 if(fl==2){
105                     x+=xx[k],y+=yy[k];
106                     if(check(x,y,s)!=1) continue;
107                 }
108                 t=(s^bin[id[i][j]])|bin[id[x][y]];
109                 if(mp[1].find(t)!=mp[1].end())
110                     continue;
111                 if(mp[0].find(t)!=mp[0].end())
112                     {ans=1;break;}
113                 mp[1][t]=1;
114                 if(c<3) q[1].push(node(t,c+1));
115                 if(ans==1) break;
116             }
117         }
118         }
119     }
120     if(ans==1)
121         printf("YES\n");
122     else
123         printf("NO\n");
124     mp[0].clear();
125     mp[1].clear();
126     }
127     return 0;
128 }

猜你喜欢

转载自www.cnblogs.com/guapisolo/p/10003072.html