[NOIP2013 提高组] 华容道 P1979 洛谷

强烈推荐,更好的阅读体验

经典题目:spfa+bfs+转化

题目大意:

给出一个01网格图,和点坐标x,y空格坐标a,b,目标位置tx,ty要求移动空格最少步数使点到tx,ty

本题关键:

我们可以发现本题可以用BFS获得很高的暴力分,但是也可以使用DP:

$f[i][j][x][y]表示空格在i,j目标点在x,y的最少操作次数$

但是本题的多次询问给我们一个启发-->可以预处理

所有我们可能可以预先处理一些状态的转移

可以发现很多状态是无效的,对于一个正确的移动路径:一定由两个部分组成

1.空格移动到目标格附近-->2.目标格借助空格移动到终点

对于前者很容易独立求出,对于后者,我们单独优化

目标点与空格的位置合并为一个状态,容易发现这个状态是4维的,空间卡住,时间__了

优化状态:

$f[i][j][0/1/2/3]表示目标点x=i,y=j,空格在其上下左右的相邻位置的状态$

为什么可以这样定义:因为在目标格借助空格移动到终点的过程中

假设目标点是下图黄球,空格只能是蓝球不能是绿球

不需要怎么了

状态之间的联系:

相邻状态:黄球位置确定下的所有蓝球位置(有效<=4)

所有对于一个状态考虑的转移左右3+1个

另外一个是空格目标交换位置(下图两种情况)

下面就可以上代码了

  1. 1 //先看主函数
  2. 2 #include<bits/stdc++.h>
  3. 3 #define ll int
  4. 4 #define f(i,a,b) for(ll i=a;i<=b;i++)
  5. 5 #define fd(i,a,b) for(ll i=a;i>=b;i--)
  6. 6 #define il inline
  7. 7 #define gc getchar()
  8. 8 #define r(i,a) for(ll i=fir[a];i;i=e[i].nex)
  9. 9 const ll maxn=32,INF=1e9,half=10,maxm=1e5;
  10. 10 ll n,m,q;
  11. 11 using namespace std;
  12. 12 bool Map[maxn][maxn];
  13. 13 ll xa[10]={-1,0,1, 0,0,0,0};
  14. 14 ll ya[10]={0, 1,0,-1,0,0,0};
  15. 15 //下 左→ ←
  16. 16 ll f[maxn][maxn][half],cnt;
  17. 17 ll dis[maxn][maxn],fir[maxm];
  18. 18 //把所有数组定义提前,以免重复或re
  19. 19 struct edge{ll to,nex,w;}e[maxm<<1];
  20. 20
  21. 21 il void add(ll a,ll b,ll c){e[++cnt].to=b,e[cnt].nex=fir[a],e[cnt].w=c;fir[a]=cnt;}
  22. 22
  23. 23 //↑用于spfa的建边,在dfs中建边
  24. 24 ll getnum(ll x,ll y){return ((x-1)*(m)+y)<<2;}
  25. 25 //对于每个空格与目标个相邻的状态进行编号
  26. 26 ll fat(ll x){return (x+2)%4;}
  27. 27 //空格相对于目标格的位置下上右左-->上下左→
  28. 28 queue<pair<ll,ll> >que;
  29. 29 //记录空格在s的d方位
  30. 30 il void bfs(ll a,ll b,ll x,ll y,ll d){//重复使用bfs
  31. 31 //a,b是枚举格子,x,y是空格
  32. 32 memset(dis,-1,sizeof(dis));
  33. 33 dis[a][b]=1;//防止被加入队列
  34. 34 dis[x][y]=0;
  35. 35 que.push(make_pair(x,y));
  36. 36 while(!que.empty()){
  37. 37 ll ux=que.front().first,uy=que.front().second;
  38. 38 que.pop();
  39. 39 f(i,0,3){
  40. 40 ll vx=ux+xa[i],vy=uy+ya[i];
  41. 41 if(Map[vx][vy]&&dis[vx][vy]==-1){
  42. 42 que.push(make_pair(vx,vy));
  43. 43 dis[vx][vy]=dis[ux][uy]+1;
  44. 44 }
  45. 45 }
  46. 46 }
  47. 47 if(d==5) return;//用于每次处理最少空格单独行走步数
  48. 48 ll num=getnum(a,b);
  49. 49 f(i,0,3){
  50. 50 ll vx=a+xa[i],vy=b+ya[i];
  51. 51 if(dis[vx][vy]>0)
  52. 52 //状态连边
  53. 53 add(num+d,num+i,dis[vx][vy]);
  54. 54 }
  55. 55 //交换位置,getnum表示相对位置取反
  56. 56 add(num+d,getnum(x,y)+fat(d),1);
  57. 57 }
  58. 58 ll far[maxm];
  59. 59 bool vis[maxm];
  60. 60 queue<ll> Q;
  61. 61 il void spfa(ll sx,ll sy){//基本的spfa
  62. 62 memset(far,-1,sizeof(far));//mem-1可以相当于赋值
  63. 63 ll num=getnum(sx,sy);
  64. 64 f(i,0,3){
  65. 65 ll vx=sx+xa[i],vy=sy+ya[i];
  66. 66 if(dis[vx][vy]!=-1){
  67. 67 far[num+i]=dis[vx][vy];
  68. 68 Q.push(num+i);
  69. 69 }
  70. 70 }
  71. 71 //↑压入起始状态(<=4种)
  72. 72 while(!Q.empty()){
  73. 73 ll u=Q.front();
  74. 74 Q.pop();
  75. 75 vis[u]=0;
  76. 76 r(i,u){
  77. 77 ll v=e[i].to;
  78. 78 if(far[v]>far[u]+e[i].w||far[v]==-1){
  79. 79 far[v]=far[u]+e[i].w;
  80. 80 if(!vis[v]){
  81. 81 Q.push(v);
  82. 82 vis[v]=1;
  83. 83 }
  84. 84 }
  85. 85 }
  86. 86 }
  87. 87 }
  88. 88 int main()
  89. 89 {
  90. 90 cin>>n>>m>>q;
  91. 91 f(i,1,n) f(j,1,m) cin>>Map[i][j];
  92. 92 f(i,1,n){
  93. 93 f(j,1,m){
  94. 94 if(!Map[i][j]) continue;
  95. 95 f(o,0,3){
  96. 96 //处理每相邻状态的空格移动的最小步数
  97. 97 //包括目标点不动空格动(<=3种),目标空格交换位置(1种)
  98. 98 ll x=i+xa[o],y=j+ya[o];
  99. 99 if(Map[x][y]) bfs(i,j,x,y,o);
  100. 100 }
  101. 101 }
  102. 102 }
  103. 103 ll sx,sy,ex,ey,tx,ty,ans;
  104. 104 while(q--){
  105. 105 ans=INF;
  106. 106 cin>>ex>>ey>>sx>>sy>>tx>>ty;
  107. 107 if(sx==tx&&sy==ty){cout<<0<<endl;continue;}
  108. 108 bfs(sx,sy,ex,ey,5);
  109. 109 //借用bfs求出空格独立行走最短路
  110. 110 spfa(sx,sy);
  111. 111 ll num=getnum(tx,ty);
  112. 112 f(i,0,3)
  113. 113 if(far[num+i]!=-1) ans=min(ans,far[num+i]);
  114. 114 cout<<((ans==INF)?-1:ans)<<endl;
  115. 115 }
  116. 116 }

[NOIP2013 提高组] 华容道 P1979 洛谷的更多相关文章

  1. NOIP2017提高组Day2T3 列队 洛谷P3960 线段树

    原文链接https://www.cnblogs.com/zhouzhendong/p/9265380.html 题目传送门 - 洛谷P3960 题目传送门 - LOJ#2319 题目传送门 - Vij ...

  2. NOIP2017提高组Day2T2 宝藏 洛谷P3959 状压dp

    原文链接https://www.cnblogs.com/zhouzhendong/p/9261079.html 题目传送门 - 洛谷P3959 题目传送门 - Vijos P2032 题意 给定一个 ...

  3. NOIP 2016 提高组 复赛 Day2T1==洛谷2822 组合数问题

    题目描述 组合数表示的是从n个物品中选出m个物品的方案数.举个例子,从(1,2,3) 三个物品中选择两个物品可以有(1,2),(1,3),(2,3)这三种选择方法.根据组合数的定 义,我们可以给出计算 ...

  4. NOIP2018&2013提高组T1暨洛谷P5019 铺设道路

    题目链接:https://www.luogu.org/problemnew/show/P5019 花絮:普及蒟蒻终于A了一道提高的题目?emm,写一篇题解纪念一下吧.求过! 分析: 这道题我们可以采用 ...

  5. [NOIP2013提高组]华容道

    这道题第一眼看是暴力,然后发现直接暴力会TLE. 把问题转换一下:移动空格到处跑,如果空格跑到指定位置的棋子,交换位置. 这个可以设计一个状态:$[x1][y1][x2][y2]$,表示空格在$(x1 ...

  6. [NOIp2013提高组]积木大赛/[NOIp2018提高组]铺设道路

    [NOIp2013提高组]积木大赛/[NOIp2018提高组]铺设道路 题目大意: 对于长度为\(n(n\le10^5)\)的非负数列\(A\),每次可以选取一个区间\(-1\).问将数列清零至少需要 ...

  7. NOIP2013 提高组 Day2

    期望得分:100+100+30+=230+ 实际得分:100+70+30=200 T2 觉得题目描述有歧义: 若存在2i却不存在2i+1,自己按不合法做的,实际是合法的 T3  bfs 难以估分 虽然 ...

  8. [NOIP2013提高组]火柴排队

    题目:洛谷P1966.Vijos P1842.codevs3286. 题目大意:有两排火柴,每根都有一个高度.设a.b分别表示两排火柴的高度,现在要令$\sum(a_i-b_i)^2$最小.现两排火柴 ...

  9. [NOIP2013提高组] CODEVS 3287 火车运输(MST+LCA)

    一开始觉得是网络流..仔细一看应该是最短路,再看数据范围..呵呵不会写...这道题是最大生成树+最近公共祖先.第一次写..表示各种乱.. 因为要求运输货物质量最大,所以路径一定是在最大生成树上的.然后 ...

随机推荐

  1. 在按照ROS官方步骤操作,同时用Git管理整个过程,git clone的新catkin_ws报错: catkin_package() include dir 'include' does not exist relative to

    在按照ROS官方步骤操作,同时用Git管理整个过程,git clone的新catkin_ws报错如下: CMake Error at /opt/ros/kinetic/share/catkin/cma ...

  2. Linux服务器JDK的安装

    JDK安装 开发java程序必须要的环境 下载JDK rpm. 安装环境 #检测当前系统是否安装Java环境 java -version #如果有就需要卸载 #rpm -qa|grep jdk #检测 ...

  3. python 动图gif合成与分解

    合成 #!/usr/bin/env python3 # -*- coding: utf-8 -*- import os import sys import imageio def main(imgs_ ...

  4. thymeleaf+layui加载页面渲染时报错

    将freemaker替换成thymeleaf时出现以下问题: org.thymeleaf.exceptions.TemplateProcessingException: Could not parse ...

  5. SpringBoot整合定时任务----Scheduled注解实现(一个注解全解决)

    一.使用场景 定时任务在开发中还是比较常见的,比如:定时发送邮件,定时发送信息,定时更新资源,定时更新数据等等... 二.准备工作 在Spring Boot程序中不需要引入其他Maven依赖 (因为s ...

  6. 【进阶之路】持续集成、持续交付与持续部署(CI/CD)

    由来 记得7月份刚刚换工作的时候,中午和老大一起去吃饭,回来的路上老大问我:"南橘,CI/CD有没有研究过?" 我隐隐约约在哪里听过这个名词,但是又想不起来,秉着实事求是的态度,我 ...

  7. PyCharm——滚动鼠标调整字体大小

  8. C# 爬虫框架实现 概述

    目录: C# 爬虫框架实现 概述 C# 爬虫框架实现 流程_爬虫结构/原理 C# 爬虫框架实现 流程_各个类开发 C# 爬虫框架实现 流程_遇到的问题 C# 爬虫框架实现 后记 C#爬虫框架实现 源代 ...

  9. 网络协议之TCP和UDP

    TCP/IP协议: 传输控制协议/因特网互联协议( Transmission Control Protocol/Internet Protocol),是Internet最基本.最广泛的协议.它定义了计 ...

  10. Mybatis log plugin插件破解修复版 MyBatis Log Plugin License Authorization Failed

    github地址 - https://github.com/Link-Kou/intellij-mybaitslog