传送门

广搜

4*4 的方阵只有 0 和 1

显然可以状态压缩

(如样例的开始状态压缩后就是1111000011100010)

为了加快速度用了双向广搜(顺便学了一下双向广搜)

双向广搜顾名思义

就是从起点和终点两个方向广搜

每次选择扩展步数少的扩展一层

然后一旦一个状态被两边都找到了

那就把两边的步数加一下,就是答案了

然后要注意位运算的细节

具体实现看代码吧

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;
struct node
{
int p,stp;
};//广搜的队列,p表示状态,stp表示当前走了几步
queue <node> q[];
bool pd[][];//记忆化,pd[i][]为到i状态需要的最少步数
int ans,st,lst;
inline void add(int k,int p,int stp)
//尝试把状态p加入队列
{
if(pd[p][k^]||(p==st&&k)||(p==lst&&k==))//如果另一边已经找过了或者到了另一边的起点
//因为在起点和终点的pd为0 所以要特判一下
{
ans=stp+pd[p][k^];//更新ans
return;//直接返回
}
if(pd[p][k]||p==st||p==lst) return;//如果找过了或者回到开始点,直接返回 //否则
pd[p][k]=stp;//更新pd
node t; t.p=p; t.stp=stp;
q[k].push(t);//加入队列
}
inline void bfs()
{
int k= q[].size()<q[].size();//确定要从哪一边扩展
int now=q[k].front().stp;
while(!q[k].empty())
{
node t=q[k].front();
if(t.stp>now||ans) break;//保证一次只扩展一层
q[k].pop();//(细节)要先判断再弹出
for(int i=;i>=;i--)//向左移动
{
if(i%==) continue;//注意如果在边界就不能动
if( !(t.p& (<<i) ) || t.p& ( <<(i+) ) ) continue;//判断
add(k, t.p^ (<<i) ^ ( <<(i+) ), t.stp+);//直接异或一波得到下一步的状态
}
for(int i=;i>=;i--)//向右
{
if(i%==) continue;//同样判断
if( !(t.p& (<<i) ) || t.p& (<<(i-) ) ) continue;
add(k, t.p^ (<<i) ^ ( <<(i-) ), t.stp+);
}//同上
for(int i=;i>=;i--)//向上,注意i的范围
{
if( !(t.p& (<<i) ) || t.p& (<<(i+) ) ) continue;
add(k, t.p^ (<<i) ^ ( <<(i+) ), t.stp+);
}//同上
for(int i=;i>=;i--)//向上,同样注意i
{
if( !(t.p& (<<i) ) || t.p& (<<(i-) ) ) continue;
add(k, t.p^ (<<i) ^ ( <<(i-) ), t.stp+);
}//同上
}
}
int main()
{
char ss[]; memset(ss,,sizeof(ss));
for(int i=;i<;i++)
{
cin>>ss;
for(int j=;j<;j++)
st+=( (ss[j]-'')<<(-i*-j) );
}//读入状态
node t; t.p=st; t.stp=;
q[].push(t);//开始状态压入队列 for(int i=;i<;i++)
{
cin>>ss;
for(int j=;j<;j++)
lst+=( (ss[j]-'')<<(-i*-j) );
}
t.p=lst; q[].push(t);//同上 if(st==lst)//特判一波起点和终点状态相同的情况
{
cout<<;
return ;
} while(!ans)
bfs();//广搜找ans
cout<<ans;
}

P4289 [HAOI2008]移动玩具的更多相关文章

  1. P4289 [HAOI2008]移动玩具(bfs)

    P4289 [HAOI2008]移动玩具 双向bfs+状态压缩+记忆化搜索 双向bfs用于对bfs的优化,每次找到可扩展节点少的一边进行一次bfs,找到的第一个互相接触的点即为最短路径 矩阵范围仅4* ...

  2. luogu P4289 [HAOI2008]移动玩具

    传送门 这道题可以二进制记录状态搜索 也可以做以下考虑 若一个棋子要移动到另一个位置上去,则步数为两点的曼哈顿距离(横坐标差的绝对值+纵坐标差的绝对值),因为假设路径上有其他的棋子,可以通过移动其他棋 ...

  3. P4289 【一本通提高篇广搜的优化技巧】[HAOI2008]移动玩具

    [HAOI2008]移动玩具 题目描述 在一个 4 × 4 4\times4 4×4 的方框内摆放了若干个相同的玩具,某人想将这些玩具重新摆放成为他心中理想的状态,规定移动时只能将玩具向上下左右四个方 ...

  4. bzoj 1054: [HAOI2008]移动玩具 bfs

    1054: [HAOI2008]移动玩具 Time Limit: 10 Sec  Memory Limit: 162 MB[Submit][Status][Discuss] Description 在 ...

  5. bzoj1054: [HAOI2008]移动玩具

    hash+bfs:要注意特殊情况.(似乎连sort.lower_bound都不用数据小直接判重了... #include<cstdio> #include<cstring> # ...

  6. BZOJ 1054 [HAOI2008]移动玩具

    1054: [HAOI2008]移动玩具 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1388  Solved: 764[Submit][Statu ...

  7. 1054: [HAOI2008]移动玩具

    1054: [HAOI2008]移动玩具 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1272  Solved: 690[Submit][Statu ...

  8. 【BZOJ1054】[HAOI2008]移动玩具

    [BZOJ1054][HAOI2008]移动玩具 题面 bzoj 洛谷 题解 太\(sb\)了,不想写了,直接点开洛谷题面单击右边蓝色按钮题解即可

  9. 【BZOJ1054】[HAOI2008]移动玩具 BFS

    [BZOJ1054][HAOI2008]移动玩具 Description 在一个4*4的方框内摆放了若干个相同的玩具,某人想将这些玩具重新摆放成为他心中理想的状态,规定移动 时只能将玩具向上下左右四个 ...

随机推荐

  1. Solr5.5.3的研究之路 ---1、从Mysql导入数据并创建索引

    公司需要用到全文检索,故使用Solr,也是新人一枚,本人查看的前提是Solr已经安装部署成功,我用的服务器是自带的Jetty 1.创建Collection [root@whoami bin]# ./s ...

  2. 数据存储的两种方式:Cookie 和Web Storage(转)

    数据存储的两种方式:Cookie 和Web Storage   数据存储的两种方式:Cookie 和Web Storage 1.Cookie Cookie的作用就像你去超市购物时,第一次给你办张购物卡 ...

  3. Codeforces 1107E (Vasya and Binary String) (记忆化,DP + DP)

    题意:给你一个长度为n的01串,和一个数组a,你可以每次选择消除一段数字相同的01串,假设消除的长度为len,那么收益为a[len],问最大的收益是多少? 思路:前两天刚做了POJ 1390,和此题很 ...

  4. python pip ez_setup.py

    #!/usr/bin/env python """Bootstrap setuptools installation To use setuptools in your ...

  5. c语言学习笔记-变量、变量的命名、变量的赋值和变量的初始化

    在学习了简单的输入输出功能和了解了一些基本的运算符号之后我们可以试着做一个非常简单的计算器. 比如说想计算23+65 输入以下代码就可以了. printf("23+65=%d",2 ...

  6. PrototypePattern(23种设计模式之一)

    设计模式六大原则(1):单一职责原则 设计模式六大原则(2):里氏替换原则 设计模式六大原则(3):依赖倒置原则 设计模式六大原则(4):接口隔离原则 设计模式六大原则(5):迪米特法则 设计模式六大 ...

  7. 算法Sedgewick第四版-第1章基础-2.1Elementary Sortss-006归并排序(Mergesort)

    一. 1.特点 (1)merge-sort : to sort an array, divide it into two halves, sort the two halves (recursivel ...

  8. 移动应用中的AR开发,5款最受欢迎工具推荐!

      英文原文:Top 5 Tools for Augmented Reality in Mobile Apps 还记得前段时间在网上很火的 3D 小熊不?托它的福,为相当一部分人科普了增强现实(AR) ...

  9. [转]CMD命令提示符窗口中的快捷键、小技巧和常用命令

    转至:https://wenku.baidu.com/view/d5d2b7ca360cba1aa811dac6.html 快捷键:  F1:按F1一次,命令提示符向后切换到已经执行过的命令字符.如果 ...

  10. 值得细读!如何系统有效地提升Android代码的安全性?

    众所周知,代码安全是Android开发工作中的一大核心要素. 11月3日,安卓巴士全球开发者论坛线下系列沙龙第七站在成都顺利举办.作为中国领先的安卓开发者社区,安卓巴士近年来一直致力于在全国各大城市举 ...