题目大意:给你一个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\n");
122     else
123         printf("NO\n");
124     mp[0].clear();
125     mp[1].clear();
126     }
127     return 0;
128 }

转载于:https://www.cnblogs.com/guapisolo/p/10003072.html

POJ 1198 / HDU 1401 Solitaire (记忆化搜索+meet in middle)相关推荐

  1. HDU 漫步校园 (记忆化搜索)

    漫步校园 Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other) Total Submissi ...

  2. poj 1085 Triangle War 博弈论+记忆化搜索

    思路:总共有18条边,9个三角形. 极大极小化搜索+剪枝比较慢,所以用记忆化搜索!! 用state存放当前的加边后的状态,并判断是否构成三角形,找出最优解. 代码如下: 1 #include<i ...

  3. hdu 1078(记忆化搜索)

    题意: 老鼠每次最多走k步停下来,停下的这个位置只能比上一个停留的位置大,并获取其价值,每次只能水平或垂直走,问最大能得到的价值 解题思路:这道题可以用记忆化搜索解决,dp[i][j]表示老鼠在位置( ...

  4. How many ways HDU - 1978(记忆化搜索关于求多少种方式模板)

    题目: 这是一个简单的生存游戏,你控制一个机器人从一个棋盘的起始点(1,1)走到棋盘的终点(n,m).游戏的规则描述如下: 1.机器人一开始在棋盘的起始点并有起始点所标有的能量. 2.机器人只能向右或 ...

  5. FatMouse and Cheese HDU - 1078(记忆化搜索入门模板)

    题意: n * n的正方形格子(每个格子均放了奶酪),老鼠从(0,0)开始,每次最多移动k步,可以选择上下左右四个方向移动,下一个移动点奶酪块数量必须要大于当前点. 整理模板ing- 题目: FatM ...

  6. POJ1088 滑雪题解+HDU 1078(记忆化搜索DP)

    Description Michael喜欢滑雪百这并不奇怪, 因为滑雪的确很刺激.可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你.Michael想知道 ...

  7. hdu 4722(记忆化搜索)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4722 思路:简单的记忆化搜索,留意一下A==0时的情况就可以了. 1 #include<iost ...

  8. hdu 4597 Play Game(记忆化搜索)

    题目链接:hdu 4597 Play Game 题目大意:给出两堆牌,仅仅能从最上和最下取,然后两个人轮流取,都依照自己最优的策略.问说第一个人对多的分值. 解题思路:记忆化搜索,状态出来就很水,dp ...

  9. hdu 1142 记忆化搜索

    题目是这样的,貌似一开始我这个英语搓的人还理解错了...orz http://acm.hdu.edu.cn/showproblem.php?pid=1142 就是最短路,只不过用dijkstra是从终 ...

  10. HDU 1176 免费馅饼(记忆化搜索)

    免费馅饼 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submi ...

最新文章

  1. java里顺序表怎么判断是否满_2、顺序表的实现(java代码)
  2. 【若依(ruoyi)】工作流操作SQL
  3. 一个运维老将的自我修养
  4. BetterAndBetter(BAB)的使用详解
  5. 将DataTable 数据插入 SQL SERVER 数据库
  6. 怎样写出别人无法维护的代码
  7. SQLite使用报告
  8. oracle怎么变为整数,如何在Oracle 11g SQL中为char添加整数?(How to add integers to char in Oracle 11g SQL?)...
  9. Activiti 统一身份管理
  10. 20165205 2017-2018-2 《Java程序设计》第六周学习总结
  11. weblogic部署微服务项目
  12. 物联网——射频识别技术的应用
  13. win10计算机如何切换用户名,如何修改电脑用户名,win10系统更改用户名方法
  14. codeforces 1013 A Piles With Stones
  15. JSP传参 input隐藏域
  16. 一文了解基金投资的方法
  17. Etcher 改变一个选项,让所有盘符都乖乖出来
  18. 电脑所有的浏览器都上不了网怎么解决
  19. 2db多少功率_功率和db换算(功率与db换算表)
  20. 【百问网7天物联网智能家居】训练营学习笔记(七)

热门文章

  1. linux桌面lxde 安装_archlinux下lxde安装与配置教程
  2. 开源机器人库orocos KDL 学习笔记(二):Geometric
  3. CGCS2000转WGS84
  4. 华为大数据研发第2轮面试
  5. CSAPP:malloclab (显式空闲链表 LIFO+首次适配)
  6. Springboot毕设项目基于Vue和Springboot的会议室管理系统hbb9kjava+VUE+Mybatis+Maven+Mysql+sprnig)
  7. RabbitMQ高可用--Quorum Queue(仲裁队列)的原理
  8. Unity开发 MMORPG类游戏引导系统
  9. 【Android】Error obtaining UI hierarchyError while obtaining UI hierarchy XML file: com.android...
  10. 一文理解UDS安全访问服务(0x27)