zoukankan      html  css  js  c++  java
  • 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

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

      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
    ");
    122     else
    123         printf("NO
    ");
    124     mp[0].clear();
    125     mp[1].clear();
    126     }
    127     return 0;
    128 }
  • 相关阅读:
    Android 五大布局
    jdk6的安装以及环境变量的设置
    PLSQL Developer图形化窗口创建数据库全过程
    未能加载文件或程序集“Oracle.DataAccess, " 64位OS运行32位程序的问题
    Android SDK 无法连接到GOOGLE 下载安装包
    Android开发之旅:环境搭建
    Android开发把项目打包成apk
    在 VMware Workstation 虚拟机中创建共享文件夹的步骤〔图解〕
    谈谈对于企业级系统架构的理解
    C#图片处理之: 获取数码相片的EXIF信息
  • 原文地址:https://www.cnblogs.com/guapisolo/p/10003072.html
Copyright © 2011-2022 走看看