传送门

广搜

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. Elasticsearch之curl创建索引

    前提,是 Elasticsearch之curl创建索引库 [hadoop@djt002 elasticsearch-2.4.3]$ curl -XPUT 'http://192.168.80.200: ...

  2. Tensorflow递归神经网络学习练习

    import tensorflow as tffrom tensorflow.examples.tutorials.mnist import input_data #载入数据集mnist = inpu ...

  3. Tensorflow手写数字识别训练(梯度下降法)

    # coding: utf-8 import tensorflow as tffrom tensorflow.examples.tutorials.mnist import input_data #p ...

  4. 使用Maven搭建SSM框架(Eclipse)

    今天学习一下使用Maven搭建SSM框架,以前都是用别人配置好的框架写代码,今天试试自己配置一下SSM框架. 这里我的参数是Windows7 64位,tomcat9,eclipse-jee-neon- ...

  5. kaggle Titanic

    # coding: utf-8 # In[19]: # 0.78468 # In[20]: import numpy as np import pandas as pd import warnings ...

  6. Oracle中的学习笔记

    1.使用 ||来连接字符串 select CARD_ID ||','||CARD_TYPE as qqq from CARDS t 2.DISTINCT (唯一不重复) select DISTINCT ...

  7. GUID介绍

    GUID介绍 GUID(Global unique identifier)全局唯一标识符,它是由网卡上的标识数字(每个网卡都有唯一的标识号)以及 CPU 时钟的唯一数字生成的的一个 16 字节的二进制 ...

  8. css 隐藏html元素的方法

    1.常见方法 display:none 这个方法的问题是 元素被隐藏了 同时该元素不占位置了,应该也可以说该元素没有高度和宽度了 2.常见方法 visibility: hidden; 这个方法和dis ...

  9. JS中setTimeout()的用法详解

    1. SetTimeOut() 1.1 SetTimeOut()语法例子 1.2 用SetTimeOut()执行Function 1.3 SetTimeOut()语法例子 1.4 设定条件使SetTi ...

  10. 在类中使用Response.Redirect()方法

    问题来自:"我在app_code 定义了user.cs类:其中作了跳转:Httpcontect.Current.Response.Redirect("/c/index.aspx&q ...