题目大意:给你一个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)的更多相关文章

  1. 不要62 hdu 2089 dfs记忆化搜索

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=2089 题意: 给你两个数作为一个闭区间的端点,求出该区间中不包含数字4和62的数的个数 思路: 数位dp中 ...

  2. poj 3249(bfs+dp或者记忆化搜索)

    题目链接:http://poj.org/problem?id=3249 思路:dp[i]表示到点i的最大收益,初始化为-inf,然后从入度为0点开始bfs就可以了,一开始一直TLE,然后优化了好久才4 ...

  3. poj 1661 Help Jimmy(记忆化搜索)

    题目链接:http://poj.org/problem?id=1661 一道还可以的记忆化搜索题,主要是要想到如何设dp,记忆化搜索是避免递归过程中的重复求值,所以要得到dp必须知道如何递归 由于这是 ...

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

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

  5. hdu 1078(dfs记忆化搜索)

    题意:容易理解... 思路:我开始是用dfs剪枝做的,968ms险过的,后来在网上学习了记忆化搜索=深搜形式+dp思想,时间复杂度大大降低,我个人理解,就是从某一个点出发,前面的点是由后面的点求出的, ...

  6. poj 1088 动态规划+dfs(记忆化搜索)

    滑雪 Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u   Description Mi ...

  7. poj 1579(动态规划初探之记忆化搜索)

    Function Run Fun Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 17843   Accepted: 9112 ...

  8. POJ 3616 Milking Time ——(记忆化搜索)

    第一眼看是线段交集问题,感觉不会= =.然后发现n是1000,那好像可以n^2建图再做.一想到这里,突然醒悟,直接记忆化搜索就好了啊..太蠢了.. 代码如下: #include <stdio.h ...

  9. POJ 1661 Help Jimmy ——(记忆化搜索)

    典型的记忆化搜索问题,dfs一遍即可.但是不知道WA在哪里了= =,一直都没找出错误.因为思路是很简单的,肯定是哪里写挫了,因此不再继续追究了. WA的代码如下,希望日后有一天能找出错误= =: —— ...

随机推荐

  1. Unity 导入的模型检测不到碰撞

    解决方案 添加Mesh Collider和rigidbody,并且Collider里边2个勾要勾上. 这是我碰到的问题.如果没解决你的问题,别打我,逃~

  2. IDEA创建Maven工程依赖jar包爆红问题

    使用IDEA创建maven工程后,在pom.xml文件中添加jar包坐标依赖后报错, 如图:

  3. Java web课程学习之会话(Session)

    Session会话   l web应用中的会话是指一个客户端浏览器与web服务器之间连续发生一系列请求和响应过程 l web应用的会话状态是指web服务器与浏览器在会话过程中产生的状态信息,借助会话状 ...

  4. Docker可视化管理工具对比(DockerUI、Shipyard、Rancher、Portainer)

    1.前言 谈及docker,避免不了需要熟练的记住好多命令及其用法,对于熟悉shell.技术开发人员而言,还是可以接受的,熟练之后,命令行毕竟是很方便的,便于操作及脚本化.但对于命令行过敏.非技术人员 ...

  5. Mysql优化之优化工具profiling

    程序员的成长之路 2016-11-23 22:42 Mysql优化之优化工具profiling 前言 mysql优化技术: mysql优化不是做一个操作就可以的优化,它包含很多的细节,需要一点一点的优 ...

  6. COGS——T 1168. 机器调度

    http://www.cogs.pro/cogs/problem/problem.php?pid=1168 ★★   输入文件:machine.in   输出文件:machine.out   简单对比 ...

  7. 【原创】PHP扩展开发进阶

    PHP扩展开发进阶 ​作者:wf (360电商技术) 在第一期PHP扩展开发入门中,简单的介绍了PHP的总体架构和执行机制,并具体说明了怎样开发和编译一个主要的PHP扩展,最后在PHP 5.3的环境下 ...

  8. 15 个经常使用的 SQL Server 高级语法

    1.case-end (详细的值) case后面有值,相当于c#中的switch case 注意:case后必须有条件,而且when后面必须是值不能为条件. -----------------case ...

  9. xcode5.1生成framework,支持arm64报错

    错误例如以下: ld: Assertion failed: (_machoSection != 0), function machoSection, file /SourceCache/ld64/ld ...

  10. cocos2d-x3.2 下使用多线程

    事实上在cocos2dx下使用多线程事实上就是用C++去写,这里提供几个简单的样例: 原文地址:http://blog.csdn.net/qqmcy/article/details/36227377 ...