题目传送门

题意:给出一个$N \times M$的棋盘,棋盘上有一些块可以移动,有一些块无法移动。$Q$次询问,每一次询问给出三个块$a,b,c$,将$a$块变为空格,空格旁边可移动的块可以与空格交换位置。问每一次询问中最小的将$b$块移动到$c$块最开始位置上的移动次数。$N , M \leq 30 , Q \leq 500$


我觉得我在$NOIP$考场上绝对会直接打暴力qwq

我们能够发现空格必须要在需要移动的格子的四周,而且不移动需要移动的格子,才能发挥效果。所以当空格在需要移动的格子旁边的时候,只有两种情况:①将需要移动的格子与空格交换位置;②将空格移动到需要移动的格子的另一侧。所以我们预处理:$f_{i,j,k,l}$表示将空格从格子$i,j$的方向$k$移动到方向$l$且不移动$(i,j)$的最少步数,可以通过$bfs$实现,复杂度$O(16N^2M^2)$

接下来就是一个类似于最短路的问题了。然而最开始空格与需要移动的格子不相邻,所以我们在每一次询问的时候,再一次$bfs$计算现在空格的位置到达需要移动的格子四周且不移动需要移动的格子的最少移动次数,然后跑$SPFA$即可。因为图很小,卡不了$SPFA$。

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3
  4 inline int read(){
  5     int a = 0;
  6     char c = getchar();
  7     while(!isdigit(c))
  8         c = getchar();
  9     while(isdigit(c)){
 10         a = (a << 3) + (a << 1) + (c ^ '0');
 11         c = getchar();
 12     }
 13     return a;
 14 }
 15
 16 const int dir[4][2] = {0,1,1,0,-1,0,0,-1};
 17 int f[31][31][4][4] , dis[31][31][4] , t[31][31] , N , M , Q;
 18 bool canbe[32][32] , inq[31][31][4];
 19 struct be{
 20     int x , y , dir;
 21 }now;
 22
 23 queue < pair < int , int > > q;
 24 queue < be > q1;
 25
 26 inline int SPFA(int aX , int aY , int bX , int bY , int cX , int cY){
 27     while(!q.empty())
 28         q.pop();
 29     if(!canbe[aX][aY] || !canbe[bX][bY])
 30         return 0x3f3f3f3f;
 31     memset(t , 0x3f , sizeof(t));
 32     t[aX][aY] = 0;
 33     q.push(make_pair(aX , aY));
 34     while(!q.empty()){
 35         pair < int , int > r = q.front();
 36         q.pop();
 37         if(r.first == bX && r.second == bY)
 38             return t[bX][bY];
 39         for(int i = 0 ; i < 4 ; i++)
 40             if(r.first + dir[i][0] != cX || r.second + dir[i][1] != cY)
 41                 if(canbe[r.first + dir[i][0]][r.second + dir[i][1]])
 42                     if(t[r.first + dir[i][0]][r.second + dir[i][1]] > t[r.first][r.second] + 1){
 43                         t[r.first + dir[i][0]][r.second + dir[i][1]] = t[r.first][r.second] + 1;
 44                         q.push(make_pair(r.first + dir[i][0] , r.second + dir[i][1]));
 45                     }
 46     }
 47     return 0x3f3f3f3f;
 48 }
 49
 50 inline void bfs(int sX , int sY , int tX , int tY){
 51     for(int i = 0 ; i < 4 ; i++)
 52         if(dis[sX][sY][i] != 0x3f3f3f3f){
 53             inq[sX][sY][i] = 1;
 54             q1.push((be){sX , sY , i});
 55         }
 56     while(!q1.empty()){
 57         now = q1.front();
 58         inq[now.x][now.y][now.dir] = 0;
 59         q1.pop();
 60         if(now.x == tX && now.y == tY)
 61             continue;
 62         for(int i = 0 ; i < 4 ; i++)
 63             if(now.dir != i){
 64                 int N = dis[now.x][now.y][now.dir] + f[now.x][now.y][now.dir][i];
 65                 if(dis[now.x][now.y][i] > N){
 66                     dis[now.x][now.y][i] = N;
 67                     if(!inq[now.x][now.y][i]){
 68                         inq[now.x][now.y][i] = 1;
 69                         q1.push((be){now.x , now.y , i});
 70                     }
 71                 }
 72             }
 73         if(dis[now.x + dir[now.dir][0]][now.y + dir[now.dir][1]][3 - now.dir] > dis[now.x][now.y][now.dir] + 1){
 74             dis[now.x + dir[now.dir][0]][now.y + dir[now.dir][1]][3 - now.dir] = dis[now.x][now.y][now.dir] + 1;
 75             if(!inq[now.x + dir[now.dir][0]][now.y + dir[now.dir][1]][3 - now.dir]){
 76                 inq[now.x + dir[now.dir][0]][now.y + dir[now.dir][1]][3 - now.dir] = 1;
 77                 q1.push((be){now.x + dir[now.dir][0] , now.y + dir[now.dir][1] , 3 - now.dir});
 78             }
 79         }
 80     }
 81 }
 82
 83 int main(){
 84     N = read();
 85     M = read();
 86     Q = read();
 87     for(int i = 1 ; i <= N ; i++)
 88         for(int j = 1 ; j <= M ; j++)
 89             canbe[i][j] = read();
 90     memset(f , 0x3f , sizeof(f));
 91     for(int i = 1 ; i <= N ; i++)
 92         for(int j = 1 ; j <= M ; j++)
 93             if(canbe[i][j])
 94                 for(int m = 0 ; m <= 3 ; m++)
 95                     for(int n = 0 ; n <= 3 ; n++)
 96                         f[i][j][m][n] = SPFA(i + dir[m][0] , j + dir[m][1] , i + dir[n][0] , j + dir[n][1] , i , j);
 97     while(Q--){
 98         int a = read() , b = read() , c = read() , d = read() , e = read() , f = read();
 99         if(c == e && d == f){
100             printf("0\n");
101             continue;
102         }
103         memset(dis , 0x3f , sizeof(dis));
104         for(int i = 0 ; i < 4 ; i++)
105             dis[c][d][i] = SPFA(a , b , c + dir[i][0] , d + dir[i][1] , c , d);
106         bfs(c , d , e , f);
107         int ans = 0x3f3f3f3f;
108         for(int i = 0 ; i < 4 ; i++)
109             ans = min(ans , dis[e][f][i]);
110         printf("%d\n" , ans == 0x3f3f3f3f ? -1 : ans);
111     }
112     return 0;
113 }

转载于:https://www.cnblogs.com/Itst/p/9782108.html

Luogu1979 NOIP2013D2T3 华容道 搜索、最短路相关推荐

  1. NOIP 2017 逛公园 记忆化搜索 最短路 好题

    题目描述: 策策同学特别喜欢逛公园.公园可以看成一张N个点MM条边构成的有向图,且没有 自环和重边.其中1号点是公园的入口,N号点是公园的出口,每条边有一个非负权值, 代表策策经过这条边所要花的时间. ...

  2. 算法提高课-搜索-最短路模型-AcWing 1076. 迷宫问题:bfs最短路、路径

    题目分析 分析: bfs求最短路,主要原因是因为bfs是一层一层的搜,当第一次搜到终点的时候,其实就是到终点的最短路. 本题bfs倒着搜,从终点(n-1,n-1)开始搜,记录到每个点的路径nxt[][ ...

  3. 【CCCC】L3-014 周游世界 (30分),,DFS搜索最短路,路径打印

    problem L3-014 周游世界 (30分) 周游世界是件浪漫事,但规划旅行路线就不一定了-- 全世界有成千上万条航线.铁路线.大巴线,令人眼花缭乱.所以旅行社会选择部分运输公司组成联盟,每家公 ...

  4. BZOJ 3891 USACO 2014 Dec Piggy Back 搜索 最短路

    第一个人从1出发边权A,第二个人从2出发边权B,走到一起边权C,求最短方案使两人走到n. 分别从1,2,n跑一次最短路,然后枚举走到一起的点计算答案即可. 没开快速读入 104ms,开快速读入84ms ...

  5. 算法提高课-搜索-最短路模型-AcWing 1100. 抓住那头牛:bfs

    题目分析 来源:acwing 分析:bfs求最短步数,需要dist[]数组来记录最短步数. ac代码 #include<bits/stdc++.h> using namespace std ...

  6. 算法提高课-搜索-最短路模型-AcWing 188. 武士风度的牛 :bfs、dist数组记录最小步数

    题目分析 来源:acwing 分析:马走日,这里用bfs遍历马的行走过程,输出到达终点的最小步数. 使用bfs求到每个点的最小步数,需要开一个dist[][]数组,来记录起点到某点的最小步数. 队列里 ...

  7. [CSP-S模拟测试]:chess(搜索+最短路)

    题目描述 $pig$在下象棋的时候特别喜欢用马,他总是计算着自己的马还需要几步才能吃掉对方的帅,以及方案数的个数,当然$pig$很笨,所以他只能求助于你. 我们假设在$n\times m$的棋盘上,$ ...

  8. 算法基础知识总结(搜索与图论)

    三.搜索与图论 1.树与图的深度优先遍历 1.基本思想:利用深度优先搜素 2.树与图的存储与时间复杂度: (1)邻接矩阵:O(∣V∣2)O(|V|^2)O(∣V∣2) (2)邻接表:O(∣V∣+∣E∣ ...

  9. NOIP 好题推荐(DP+搜索+图论)POJ ZOJ

    NOIP好题推荐(DP+搜索+图论)POJ ZOJ 1370 Gossiping (数论->模线性方程有无解的判断)+(图论->DFS)  1090 Chain ->格雷码和二进制码 ...

最新文章

  1. dom4j的读写XML文件
  2. c# 利用反射获得某个类或者对象的所有属性
  3. 如何写一个优秀的GitHub项目README文档?
  4. 200820C阶段一通用链表
  5. iOS开发-开发总结(四)
  6. Codeforces Round #444 (Div. 2) C.Solution for Cube 模拟
  7. dubbo使用nacos作为注册中心
  8. c语言atof字母,C语言字符转换之atof()
  9. hbase查看表结构_HBase 常用 Shell 命令手册
  10. 【接口测试】接口和接口文档概念
  11. 鼠标锁定计算机全部硬盘,最牛B的清理磁盘方法,让你电脑开机贼拉快快
  12. JDK11的下载安装以及环境配置
  13. 马士兵老师Java虚拟机调优
  14. 基于深度学习安卓端烟雾和火焰检测开发总结
  15. 查看ftp服务器里的文件,查看ftp服务器所有文件
  16. ubuntu--ogv格式转mp4格式
  17. VC6.0(VC++6.0)使用教程(使用VC6.0编写C语言程序)
  18. FlowJO X 流式补偿调整
  19. js计算两个时间相差的年、月、日、时、分、秒。
  20. Rikka with Travels

热门文章

  1. osgi框架 android,基于OSGi的Android应用模块动态加载框架设计与实现
  2. 哈希表数据结构_算法与数据结构-哈希表
  3. Android Studio无线连接设备调试,比数据线更方便
  4. Java 多线程 —— AQS 原理
  5. scrapy没有运行结果_关于Scrapy爬虫项目运行和调试的小技巧(下篇)
  6. 虚拟接口+tx+linux,Linux使用笔记: 解决Xen虚拟机中VLAN接口不能ping大包的问题
  7. 唯有自己变得强大_唯有自己变得强大,才能获得有用人脉!
  8. 监控视图 oracle,Oracle“并行执行”之四——监控视图
  9. java list应用_java中list集合的应用
  10. java - 求最大公约数和最小公倍数