题目戳我

懒得粘贴题目了。。就这要凑合一下吧。。。

题解

反正棋盘的状态不会变的。。。

所以,预处理一下???

恩,如果一个棋子要移动到某个目标位置的话,

可以看成只有空格和这个子要动呀(其他的有区别吗??)

因此,我们考虑预处理一个数组move[i][j][k][l]

表示在(i,j)位置,空格在k方向的时候,移动到l方向的最短距离

至于方向是哪边就自己定义一下吧。。

那么,这个预处理,直接跑BFS就行了。。。

最后对于每一个状态求解,

只要先让空格到达移动的棋子旁边,在利用move数组跑SPFA就行了(很显然的呀。。。)

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#include<vector>
using namespace std;
#define INF 1000000000
inline int read()
{
int x=0,t=1;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=-1,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return x*t;
}
int N,M,Q;
int d[5][2]={0,1,0,-1,1,0,-1,0,0,0};
int g[50][50],far[50][50],Ans[50][50][4];
bool vis[50][50];
bool Vis[50][50][4];
int dis[50][50][4][4];
int Tx,Ty,Sx,Sy,Ex,Ey;
struct Node
{
int x,y,st;
};
struct Dalao
{
int x,y,fr;
};
inline void BFS(int X,int Y,int dd)
{
queue<Node> Q;while(!Q.empty())Q.pop();
memset(vis,0,sizeof(vis));
for(int i=1;i<=N;++i)
for(int j=1;j<=M;++j)
far[i][j]=INF;
Q.push((Node){X+d[dd][0],Y+d[dd][1],0});
vis[X][Y]=true;
vis[X+d[dd][0]][Y+d[dd][1]]=true;
far[X][Y]=0;
if(dd==4)
vis[Sx][Sy]=true;
while(!Q.empty())
{
Node now=Q.front();
int st=now.st,xx=now.x,yy=now.y;Q.pop();
for(int i=0;i<4;++i)
{
int x=xx+d[i][0],y=yy+d[i][1];
if(!g[x][y])continue;
if(vis[x][y])continue;
vis[x][y]=true;
far[x][y]=st+1;
Q.push((Node){x,y,st+1});
}
}
}
void BFS(int Sx,int Sy)
{
queue<Dalao> Q;while(!Q.empty())Q.pop();
memset(Vis,0,sizeof(Vis));
for(int i=1;i<=N;++i)
for(int j=1;j<=M;++j)
for(int k=0;k<4;++k)
Ans[i][j][k]=INF;
for(int i=0;i<4;++i)
{
int x=Sx+d[i][0],y=Sy+d[i][1];
if(!g[x][y]||far[x][y]==INF)continue;
Q.push((Dalao){x,y,i^1});
Ans[x][y][i^1]=far[x][y]+1;
Vis[x][y][i^1]=true;
}
while(!Q.empty())
{
Dalao now=Q.front();Q.pop();
int xx=now.x,yy=now.y,fr=now.fr;
for(int i=0;i<4;++i)
{
int x=xx+d[i][0],y=yy+d[i][1];
if(!g[x][y])continue;
if(Ans[x][y][i^1]>Ans[xx][yy][fr]+dis[xx][yy][fr][i]+1)
{
Ans[x][y][i^1]=Ans[xx][yy][fr]+dis[xx][yy][fr][i]+1;
if(!Vis[x][y][i^1])
{
Q.push((Dalao){x,y,i^1});
Vis[x][y][i^1]=true;
}
}
}
Vis[xx][yy][fr]=false;
}
}
int main()
{
N=read();M=read();Q=read();
for(int i=1;i<=N;++i)
for(int j=1;j<=M;++j)
g[i][j]=read();
for(int i=1;i<=N;++i)
for(int j=1;j<=M;++j)
for(int k=0;k<4;++k)
if(g[i+d[k][0]][j+d[k][1]])
{
BFS(i,j,k);
for(int gg=0;gg<4;++gg)
{
if(gg==k)
{
dis[i][j][k][k]=INF;
continue;
}
if(g[i+d[gg][0]][j+d[gg][1]])
dis[i][j][k][gg]=far[i+d[gg][0]][j+d[gg][1]];
else
dis[i][j][k][gg]=INF;
}
}
while(Q--)
{
Ex=read(),Ey=read();//空格
Sx=read(),Sy=read();//起点
Tx=read(),Ty=read();//终点
if(Sx==Tx&&Sy==Ty)
{
printf("0\n");
continue;
}
BFS(Ex,Ey,4);
BFS(Sx,Sy);
int ans=INF;
for(int i=0;i<4;++i)ans=min(Ans[Tx][Ty][i],ans);
printf("%d\n",ans==INF?-1:ans);
}
return 0;
}

【NOIP2013】华容道(最短路)的更多相关文章

  1. LOJ2613 NOIP2013 华容道 【最短路】*

    LOJ2613 NOIP2013 华容道 LINK 这是个好题,具体题意比较麻烦可以直接看LINK中的链接 然后考虑我们可能的移动方式 首先我们需要把白块移动到需要移动块S的附近(附近四格) 然后我们 ...

  2. [NOIP2013]华容道 题解

    [NOIP2013]华容道 首先是一种比较显然的做法. 整个棋盘,除了起点,终点和空格,其他的方块是等价的. 对于终点,它始终不会变化,如果搜到终点结束搜索即可,所以我们不需要考虑终点. 所以需要考虑 ...

  3. [NOIP2013]华容道 题解(搜索)

    [NOIP2013]华容道 [题目描述] 这道题根据小时候玩华容道不靠谱的经验还以为是并查集,果断扑街.考后想想也是,数据这么小一定有他的道理. 首先由于是最小步数,所以BFS没跑了.那么我们大可把这 ...

  4. NOIP2013 华容道 (棋盘建图+spfa最短路)

    #include <cstdio> #include <algorithm> #include <cstring> #include <queue> # ...

  5. JZYZOJ1442 [noip2013]华容道 bfs 最短路 剪枝

    http://172.20.6.3/Problem_Show.asp?id=1442 想到最短路的简直神了,如果我写我大概只能写一个30分的bfs. 从数据范围可以看出思路是bfs剪枝,但这里的剪枝是 ...

  6. vijos1846 [NOIP2013] 华容道【最短路】

    传送门:https://vijos.org/p/1983 (其实noip的题各个oj都会有的,就不贴其它传送门了) 这道题真的是,怎么说,我都不知道怎么评价了= =.果然数据量小的题怎么暴力都可以过. ...

  7. loj2613 「NOIP2013」华容道[最短路]

    感觉和以前做过的一个推箱子很像,都是可以用bfs解决的,而且都是手玩出结论. 因为起始棋子肯定是要和空格交换的,所以第一件事是先把空格移到棋子旁边.然后讨论怎么设计搜索状态.由于和推箱子实在太像了,所 ...

  8. [NOIP2013]华容道

    1.题面 小 B 最近迷上了华容道,可是他总是要花很长的时间才能完成一次.于是,他想到用编程来完成华容道:给定一种局面,华容道是否根本就无法完成,如果能完成,最少需要多少时间.小 B 玩的华容道与经典 ...

  9. NOIP2013华容道 大爆搜

    预处理出每个点周围四个点互相到达的最短路,再在整个图上跑SPFA,要记录路径 #include<cstdio> #include<cstring> #include<io ...

  10. luogu P1979 [NOIP2013] 华容道

    传送门 这道题中,棋子的移动是要移动到空格上去,所以空格要在棋子旁边才能移动棋子;而棋子移动的方向由空格决定 所以我们可以记三维状态\(di_{i,j,k}\),表示状态为棋子在\((i,j)\),空 ...

随机推荐

  1. weblogic修改jdk版本遇到的问题与解决方法

    1.修改setDomainEnv ,路径.../domains/xx_domain\bin\ 1.1修改JAVA_HOME为需要修改的路径 注意:BEA_JAVA_HOME路径不需修改 2.修改路径后 ...

  2. 【Tools】ubuntu16.04升级Python2.7到3.5

    最近开始学Python,但我发现我ubuntu16.04上默认的Python是2.7,并不是3,x 于是准备Python升级,记录安装过程给初学者参考一下. 1.先取得管理员权限, 个人习惯先取得管理 ...

  3. Filezilla Server日志文件

    Filezilla Server版本:0.9.41. Filezilla Server日志文件在软件安装目录下Logs目录下. 但Filezilla Server默认不开始日志记录,如何开启filez ...

  4. python进阶学习笔记(三)

    3.类的继承 3.1,python中什么是类的继承 答案是肯定的. 也就是说,如果一个实例是一个子类,那么它也是一个父类 总是从某各类继承,如果没有合适的类,就要从object类继承:super(). ...

  5. 分布式缓存一致性hash算法理解

    今天阅读了一下大型网络技术架构这本苏中的分布式缓存一致性hash算法这一节,针对大型分布式系统来说,缓存在该系统中必不可少,分布式集群环境中,会出现添加缓存节点的需求,这样需要保障缓存服务器中对缓存的 ...

  6. LeetCode第六天

    第六天 30.(219) Contains Duplicate II JAVA class Solution { public boolean containsNearbyDuplicate(int[ ...

  7. Qt 网络模块如何使用?

    1.网络模块介绍 类名 说明 中文 QAbstractNetworkCache The interface for cache implementations 缓存实现的接口 QNetworkCach ...

  8. 【BZOJ2127】happiness

    Time Limit: 1000 ms   Memory Limit: 256 MB Description 高一一班的座位表是个n*m的矩阵,经过一个学期的相处,每个同学和前后左右相邻的同学互相成为 ...

  9. 在SpringBoot中添加Logback日志处理

    前言 SpringBoot项目中在官方文档中说明,默认已经依赖了一些日志框架.而其中推荐使用的就是Logback,所以这一次我将在我的模版中加入Logback日志的配置,说明一下,SpringBoot ...

  10. 情景linux--shell如何实现多线程?

    情景linux--shell如何实现多线程? 情景 shell脚本的执行效率虽高,但当任务量巨大时仍然需要较长的时间,尤其是需要执行一大批的命令时.因为默认情况下,shell脚本中的命令是串行执行的. ...