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\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)相关推荐
- HDU 漫步校园 (记忆化搜索)
漫步校园 Time Limit : 2000/1000ms (Java/Other) Memory Limit : 65536/32768K (Java/Other) Total Submissi ...
- poj 1085 Triangle War 博弈论+记忆化搜索
思路:总共有18条边,9个三角形. 极大极小化搜索+剪枝比较慢,所以用记忆化搜索!! 用state存放当前的加边后的状态,并判断是否构成三角形,找出最优解. 代码如下: 1 #include<i ...
- hdu 1078(记忆化搜索)
题意: 老鼠每次最多走k步停下来,停下的这个位置只能比上一个停留的位置大,并获取其价值,每次只能水平或垂直走,问最大能得到的价值 解题思路:这道题可以用记忆化搜索解决,dp[i][j]表示老鼠在位置( ...
- How many ways HDU - 1978(记忆化搜索关于求多少种方式模板)
题目: 这是一个简单的生存游戏,你控制一个机器人从一个棋盘的起始点(1,1)走到棋盘的终点(n,m).游戏的规则描述如下: 1.机器人一开始在棋盘的起始点并有起始点所标有的能量. 2.机器人只能向右或 ...
- FatMouse and Cheese HDU - 1078(记忆化搜索入门模板)
题意: n * n的正方形格子(每个格子均放了奶酪),老鼠从(0,0)开始,每次最多移动k步,可以选择上下左右四个方向移动,下一个移动点奶酪块数量必须要大于当前点. 整理模板ing- 题目: FatM ...
- POJ1088 滑雪题解+HDU 1078(记忆化搜索DP)
Description Michael喜欢滑雪百这并不奇怪, 因为滑雪的确很刺激.可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你.Michael想知道 ...
- hdu 4722(记忆化搜索)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4722 思路:简单的记忆化搜索,留意一下A==0时的情况就可以了. 1 #include<iost ...
- hdu 4597 Play Game(记忆化搜索)
题目链接:hdu 4597 Play Game 题目大意:给出两堆牌,仅仅能从最上和最下取,然后两个人轮流取,都依照自己最优的策略.问说第一个人对多的分值. 解题思路:记忆化搜索,状态出来就很水,dp ...
- hdu 1142 记忆化搜索
题目是这样的,貌似一开始我这个英语搓的人还理解错了...orz http://acm.hdu.edu.cn/showproblem.php?pid=1142 就是最短路,只不过用dijkstra是从终 ...
- HDU 1176 免费馅饼(记忆化搜索)
免费馅饼 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submi ...
最新文章
- java里顺序表怎么判断是否满_2、顺序表的实现(java代码)
- 【若依(ruoyi)】工作流操作SQL
- 一个运维老将的自我修养
- BetterAndBetter(BAB)的使用详解
- 将DataTable 数据插入 SQL SERVER 数据库
- 怎样写出别人无法维护的代码
- SQLite使用报告
- oracle怎么变为整数,如何在Oracle 11g SQL中为char添加整数?(How to add integers to char in Oracle 11g SQL?)...
- Activiti 统一身份管理
- 20165205 2017-2018-2 《Java程序设计》第六周学习总结
- weblogic部署微服务项目
- 物联网——射频识别技术的应用
- win10计算机如何切换用户名,如何修改电脑用户名,win10系统更改用户名方法
- codeforces 1013 A Piles With Stones
- JSP传参 input隐藏域
- 一文了解基金投资的方法
- Etcher 改变一个选项,让所有盘符都乖乖出来
- 电脑所有的浏览器都上不了网怎么解决
- 2db多少功率_功率和db换算(功率与db换算表)
- 【百问网7天物联网智能家居】训练营学习笔记(七)
热门文章
- linux桌面lxde 安装_archlinux下lxde安装与配置教程
- 开源机器人库orocos KDL 学习笔记(二):Geometric
- CGCS2000转WGS84
- 华为大数据研发第2轮面试
- CSAPP:malloclab (显式空闲链表 LIFO+首次适配)
- Springboot毕设项目基于Vue和Springboot的会议室管理系统hbb9kjava+VUE+Mybatis+Maven+Mysql+sprnig)
- RabbitMQ高可用--Quorum Queue(仲裁队列)的原理
- Unity开发 MMORPG类游戏引导系统
- 【Android】Error obtaining UI hierarchyError while obtaining UI hierarchy XML file: com.android...
- 一文理解UDS安全访问服务(0x27)