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
代码好长啊..但在搜索题里算短的了
#include <map>
#include <queue>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define NN 5010
#define MM 2000
#define maxn 200
#define ll long long
#define uint unsigned int
#define ull unsigned long long
using namespace std; int id[][];
int xx[]={-,,,};
int yy[]={,,,-};
ull bin[];
int ax[],ay[],bx[],by[];
struct node{
ull s;int c;
friend bool operator < (const node &s1,const node &s2)
{return s1.s<s2.s;}
node(ull s,int c):s(s),c(c){}
node(){}
};
map<ull,int>mp[];
int check(int x,int y,ull s)
{
if(x<||y<||x>||y>)return ;
if(s&bin[id[x][y]]) return ;
return ;
} int main()
{
//freopen("t2.in","r",stdin);
for(int i=;i<=;i++)
for(int j=;j<=;j++)
id[i][j]=*(i-)+j-;
//px[id[i][j]]=i,py[id[i][j]]=j;
bin[]=;
for(int i=;i<=;i++)
bin[i]=bin[i-]<<;
while(scanf("%d%d%d%d",&ax[],&ay[],&ax[],&ay[])!=EOF)
{
scanf("%d%d%d%d",&ax[],&ay[],&ax[],&ay[]);
scanf("%d%d%d%d",&bx[],&by[],&bx[],&by[]);
scanf("%d%d%d%d",&bx[],&by[],&bx[],&by[]);
queue<node>q[];
ull s=,t=;
int cnt=,fx,fy,fl,nt;
for(int i=;i<=;i++)
s|=bin[id[ax[i]][ay[i]]];
mp[][s]=;
q[].push(node(s,));s=;
for(int i=;i<=;i++)
s|=bin[id[bx[i]][by[i]]];
mp[][s]=;
q[].push(node(s,));
int ans=,c,x,y;
while((!q[].empty()||!q[].empty())&&!ans)
{
if(!q[].empty())
{
node K=q[].front();q[].pop();
s=K.s,c=K.c;
for(int i=;i<=;i++)
for(int j=;j<=;j++)
{
if(!(s&bin[id[i][j]])) continue;
for(int k=;k<;k++)
{
x=i+xx[k],y=j+yy[k];
fl=check(x,y,s);
if(!fl) continue;
if(fl==){
x+=xx[k],y+=yy[k];
if(check(x,y,s)!=) continue;
}
t=(s^bin[id[i][j]])|bin[id[x][y]];
if(mp[].find(t)!=mp[].end())
continue;
if(mp[].find(t)!=mp[].end())
{ans=;break;}
mp[][t]=;
if(c<) q[].push(node(t,c+));
if(ans==) break;
}
}
}
if(!q[].empty())
{
node K=q[].front();q[].pop();
s=K.s,c=K.c;
for(int i=;i<=;i++)
for(int j=;j<=;j++)
{
if(!(s&bin[id[i][j]])) continue;
for(int k=;k<;k++)
{
x=i+xx[k],y=j+yy[k];
fl=check(x,y,s);
if(!fl) continue;
if(fl==){
x+=xx[k],y+=yy[k];
if(check(x,y,s)!=) continue;
}
t=(s^bin[id[i][j]])|bin[id[x][y]];
if(mp[].find(t)!=mp[].end())
continue;
if(mp[].find(t)!=mp[].end())
{ans=;break;}
mp[][t]=;
if(c<) q[].push(node(t,c+));
if(ans==) break;
}
}
}
}
if(ans==)
printf("YES\n");
else
printf("NO\n");
mp[].clear();
mp[].clear();
}
return ;
}
POJ 1198 / HDU 1401 Solitaire (记忆化搜索+meet in middle)的更多相关文章
- 不要62 hdu 2089 dfs记忆化搜索
题目:http://acm.hdu.edu.cn/showproblem.php?pid=2089 题意: 给你两个数作为一个闭区间的端点,求出该区间中不包含数字4和62的数的个数 思路: 数位dp中 ...
- poj 3249(bfs+dp或者记忆化搜索)
题目链接:http://poj.org/problem?id=3249 思路:dp[i]表示到点i的最大收益,初始化为-inf,然后从入度为0点开始bfs就可以了,一开始一直TLE,然后优化了好久才4 ...
- poj 1661 Help Jimmy(记忆化搜索)
题目链接:http://poj.org/problem?id=1661 一道还可以的记忆化搜索题,主要是要想到如何设dp,记忆化搜索是避免递归过程中的重复求值,所以要得到dp必须知道如何递归 由于这是 ...
- poj 1085 Triangle War 博弈论+记忆化搜索
思路:总共有18条边,9个三角形. 极大极小化搜索+剪枝比较慢,所以用记忆化搜索!! 用state存放当前的加边后的状态,并判断是否构成三角形,找出最优解. 代码如下: #include<ios ...
- hdu 1078(dfs记忆化搜索)
题意:容易理解... 思路:我开始是用dfs剪枝做的,968ms险过的,后来在网上学习了记忆化搜索=深搜形式+dp思想,时间复杂度大大降低,我个人理解,就是从某一个点出发,前面的点是由后面的点求出的, ...
- poj 1088 动态规划+dfs(记忆化搜索)
滑雪 Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u Description Mi ...
- poj 1579(动态规划初探之记忆化搜索)
Function Run Fun Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 17843 Accepted: 9112 ...
- POJ 3616 Milking Time ——(记忆化搜索)
第一眼看是线段交集问题,感觉不会= =.然后发现n是1000,那好像可以n^2建图再做.一想到这里,突然醒悟,直接记忆化搜索就好了啊..太蠢了.. 代码如下: #include <stdio.h ...
- POJ 1661 Help Jimmy ——(记忆化搜索)
典型的记忆化搜索问题,dfs一遍即可.但是不知道WA在哪里了= =,一直都没找出错误.因为思路是很简单的,肯定是哪里写挫了,因此不再继续追究了. WA的代码如下,希望日后有一天能找出错误= =: —— ...
随机推荐
- 使用LayUI在页面实现加载层(图标)代码:
实现代码: var index = layer.load({ shade: [0.4,'#def'], icon :' 实现效果: 可以使用 layer.close(index); 来控制其在什么时 ...
- Nusoap复杂对象的的webService制作
推荐网址:http://www.scottnichol.com/nusoapprogwsdl.htm摘抄部分如下:服务器端程序 <?php // Pull in the NuSOAP code ...
- 发个ZKW线段树板子测试一下代码高亮
是我,Long time no see --Jim 先安利 Wolves 歌手:Madilyn Bailey http://music.163.com/song/524149464 ...
- 从YV12到NV12
Media SDK的decoder,vpp,encoder对输入输出格式有着严格的限制,现在仅仅支持NV12.那么如何从其他格式转化为NV12是日常工作中经常遇到的事情.本篇文章以此为目的,讨论如何将 ...
- webpack实现模块化打包
webpack打包应用和实现 1)安装webpack $ npm install webpack webpack-cli --save-dev 2)添加配置文件 webpack.config.js 3 ...
- Spring的ApplicationContextAware接口的作用
ApplicationContextAware接口: 当一个类实现了这个接口之后,这个类就可以方便地获得 ApplicationContext 中的所有bean.换句话说,就是这个类可以直接获取Spr ...
- 表单标签 fieldset legent
书写表单时可以提供简单样式的标签 <fieldset> <legent></legent> <input type="text" > ...
- UVALive 2664 One-way traffic
One-way traffic Time Limit: 3000ms Memory Limit: 131072KB This problem will be judged on UVALive. Or ...
- ASP.NET-Router配置中MapRoute的参数
App_Start文件夹中的RouteConfig MapRoute(string name,string url); MapRoute(string name,string url,object d ...
- Nginx +Tomcat 实现动静态分离(转)
Nginx +Tomcat 实现动静态分离 动静态分离就是Nginx处理客户端的请求的静态页面(html页面)或者图片,Tomcat处理客户端请求的动态页面(jsp页面),因为Nginx处理的静态页面 ...