P4289 [HAOI2008]移动玩具

双向bfs+状态压缩+记忆化搜索

双向bfs用于对bfs的优化,每次找到可扩展节点少的一边进行一次bfs,找到的第一个互相接触的点即为最短路径

矩阵范围仅4*4大小,我们容易想到用二进制数压缩其状态,利于求解。

既然转成二进制,大小又<2^17,那么可以再加数组进行记忆化

不要忘了起点终点相同时的特判qwq

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<queue>
  4. #include<cstring>
  5. using namespace std;
  6. struct data{int zip,step;};
  7. int ans,rec1[],rec2[]; //rec:记忆化用
  8. queue <data> h[]; //分别代表从起点/终点开始的bfs队列
  9. inline void check(int to,int p,data x){ //检查该点是否符合条件
  10. if(rec1[to]!=-){
  11. if(rec2[to]!=p) ans=rec1[to]+x.step+; //如果该点已被对面搜到,那么已经得出最优解
  12. }else{
  13. rec1[to]=x.step+,rec2[to]=p;
  14. h[p].push((data){to,x.step+});
  15. }
  16. }
  17. void output(int t){ //检查用,将10进制数转回4*4的二进制矩阵
  18. cout<<"---\n";
  19. int h[];
  20. for(int k=t,i=;i>=;--i) h[i]=k&,k>>=;
  21. for(int i=;i<;++i){
  22. for(int j=i*;j<=i*+;++j) cout<<h[j];
  23. cout<<endl;
  24. }
  25. cout<<"---\n";
  26. }
  27. inline void bfs(){
  28. int p=(h[].size()>h[].size()),now=(h[p].front()).step; //找到可扩展节点少的一边,并且只扩展一层
  29. while(!h[p].empty()){
  30. data x=h[p].front();
  31. if(x.step!=now||ans) break;
  32. h[p].pop();
  33. int k=,to;
  34. for(int i=;i<;i<<=,++k){ //用二进制数表示转移过程
  35. if(!(x.zip&i)) continue;
  36. if(k%!=&&(!(x.zip&(i<<)))){ //向左
  37. to=x.zip-i+(i<<);
  38. check(to,p,x);
  39. }
  40. if(k%!=&&(!(x.zip&(i>>)))){ //向右
  41. to=x.zip-i+(i>>);
  42. check(to,p,x);
  43. }
  44. if(k>&&(!(x.zip&(i>>)))){ //向下
  45. to=x.zip-i+(i>>);
  46. check(to,p,x);
  47. }
  48. if(k<&&(!(x.zip&(i<<)))){ //向上
  49. to=x.zip-i+(i<<);
  50. check(to,p,x);
  51. }
  52. }
  53. }
  54. }
  55. int main(){
  56. memset(rec1,-,sizeof(rec1));
  57. char q[]; int tot1=,tot2=;
  58. for(int i=;i<=;++i){ //矩阵转成十进制数
  59. cin>>q;
  60. for(int j=;j<=;++j) tot1+=q[j]-,tot1<<=;
  61. }tot1>>=; //注意最后要右移一位
  62. h[].push((data){tot1,}); rec1[tot1]=; rec2[tot1]=;
  63. for(int i=;i<=;++i){
  64. cin>>q;
  65. for(int j=;j<=;++j) tot2+=q[j]-,tot2<<=;
  66. }tot2>>=;
  67. h[].push((data){tot2,}); rec1[tot2]=; rec2[tot2]=;
  68. while(!ans&&tot1!=tot2) bfs(); //注意特判
  69. printf("%d",ans);
  70. return ;
  71. }

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

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

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

  2. [BZOJ1054][HAOI2008]移动玩具 bfs+hash

    1054: [HAOI2008]移动玩具 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2432  Solved: 1355[Submit][Stat ...

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

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

  4. P4289 [HAOI2008]移动玩具

    传送门 广搜 4*4 的方阵只有 0 和 1 显然可以状态压缩 (如样例的开始状态压缩后就是1111000011100010) 为了加快速度用了双向广搜(顺便学了一下双向广搜) 双向广搜顾名思义 就是 ...

  5. luogu P4289 [HAOI2008]移动玩具

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

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

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

  7. bzoj1054: [HAOI2008]移动玩具

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

  8. BZOJ 1054 [HAOI2008]移动玩具

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

  9. 1054: [HAOI2008]移动玩具

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

随机推荐

  1. Oracle管理监控之Oracle用户权限

    数据字典 1.动态数据字典是以v$xxx开始的数据字典,在数据库中约有150个左右,这些数据字典反映数据库动态运行状况,在不同时间查询会得到不同的结果. 2.DBA数据字典是以DBA_xxx表示,该数 ...

  2. free详解

    用法: [oracle@server36 ~]$ free -help free: invalid option -- h usage: free [-b|-k|-m|-g] [-l] [-o] [- ...

  3. Docker处理日志的方法&日志收集工具比较

    测试logstash:docker run -it mylogstash:0.1.0 logstash -e 'input{stdin{}}output{stdout{codec=>rubyde ...

  4. 洛谷P1084 疫情控制 [noip2012] 贪心+树论+二分答案 (还有个小bugQAQ

    正解:贪心+倍增+二分答案 解题报告: 正好想做noip的题目然后又想落实学长之前讲的题?于是就找上了这题 其实之前做过,70,然后实在细节太多太复杂就不了了之,现在再看一遍感觉又一脸懵了... 从标 ...

  5. post方式提交数据

    <!DOCTYPE HTML><html>    <head>        <meta charset="utf-8" />   ...

  6. mysql 权限管理 针对表的字段 级别 授权 columns_priv表

    针对Mike账号 db1库下面的t1表的 id,name字段授予select权限,age字段授予update权限 授权格式 select(要授权的字段,要授权的字段) 用户括号 括起来  .updat ...

  7. python 面向对象 issubclass

    判断是否 他的父类 class Foo(object): pass obj = Foo() class Boo(Foo): pass class Coo(Boo): pass obj = Boo() ...

  8. CentOS工作内容(三)配置网络IP地址

    CentOS工作内容(三)配置网络IP地址 用到的快捷键 tab 自动补齐(有不知道的吗) ctrl+a 移动到当前行的开头(a ahead) ctrl+u 删除(剪切)此处至开始所有内容 vim 末 ...

  9. java-JProfiler(五)-监控性能

    原文地址:http://blog.csdn.net/chendc201/article/details/22897999 一.基础认识 1. 在Live Memory视图里右击相关类,选中Mark C ...

  10. Java-小技巧-002-String 转 long

    1.转化 long l = Long.parseLong([String]); 相当于 long l = Long.parseLong([String],10); long l = Long.valu ...