LOJ2613 NOIP2013 华容道 【最短路】*
LOJ2613 NOIP2013 华容道
这是个好题,具体题意比较麻烦可以直接看LINK中的链接
然后考虑我们可能的移动方式
首先我们需要把白块移动到需要移动块S的附近(附近四格)
然后我们就可以考虑怎么对S进行移动
- 操作一:把S和白块互换位置
- 操作二:把白块从S的一个方向移动到另一方向(方便交换位置)
第一种操作的代价是1很显然,后一种操作我们每次移动的最小代价是可以预处理的
然后我们就可以定义状态x,y,dir表示S在(x,y)且白块在S的dir方向上
我们就只需要考虑在状态之间进行转移,用spfa就够了
#include<bits/stdc++.h>
using namespace std;
#define N 40
#define INF 0x3f3f3f3f
int mx[]={,,,-};
int my[]={,-,,};
int mv[N][N][][];
int dp[N][N][];
bool inq[N][N][];
int g[N][N],dis[N][N];
int n,m,q;
int ex,ey,sx,sy,tx,ty;
struct Node1{int x,y;};
struct Node2{int x,y,dir;};
bool check_in(int x,int y){return (x>&&x<=n&&y>&&y<=m)&&g[x][y];}
void bfs1(int x,int y,int dir){
if(!check_in(x+mx[dir],y+my[dir]))return;
static queue<Node1> q;
memset(dis,0x3f,sizeof(dis));
dis[x][y]=-;
dis[x+mx[dir]][y+my[dir]]=;
q.push((Node1){x+mx[dir],y+my[dir]});
while(!q.empty()){
Node1 now=q.front();q.pop();
for(int i=;i<;i++){
int nx=now.x+mx[i];
int ny=now.y+my[i];
if(!check_in(nx,ny))continue;
if(dis[nx][ny]>dis[now.x][now.y]+){
dis[nx][ny]=dis[now.x][now.y]+;
q.push((Node1){nx,ny});
}
}
}
for(int i=;i<;i++){
int nx=x+mx[i];
int ny=y+my[i];
if(check_in(nx,ny))mv[x][y][dir][i]=dis[nx][ny];
}
}
void bfs2(){
memset(dis,0x3f,sizeof(dis));
static queue<Node1> q;
dis[ex][ey]=;
dis[sx][sy]=-;
q.push((Node1){ex,ey});
while(!q.empty()){
Node1 now=q.front();q.pop();
for(int i=;i<;i++){
int nx=now.x+mx[i];
int ny=now.y+my[i];
if(!check_in(nx,ny))continue;
if(dis[nx][ny]>dis[now.x][now.y]+){
dis[nx][ny]=dis[now.x][now.y]+;
q.push((Node1){nx,ny});
}
}
}
}
#define NOW now.x][now.y][now.dir
int spfa(){
memset(dp,0x3f,sizeof(dp));
memset(inq,,sizeof(inq));
static queue<Node2> nq;
for(int i=;i<;i++){
int nx=sx+mx[i];
int ny=sy+my[i];
if((!check_in(nx,ny))||dis[sx+mx[i]][sy+my[i]]==INF)continue;
dp[sx][sy][i]=dis[sx+mx[i]][sy+my[i]];
nq.push((Node2){sx,sy,i});
inq[sx][sy][i]=;
}
while(!nq.empty()){
Node2 now=nq.front();nq.pop();
inq[NOW]=;
for(int i=;i<;i++)
if(dp[now.x][now.y][i]>dp[NOW]+mv[NOW][i]){
dp[now.x][now.y][i]=dp[NOW]+mv[NOW][i];
if(!inq[now.x][now.y][i]){
inq[now.x][now.y][i]=;
nq.push((Node2){now.x,now.y,i});
}
}
int nx=now.x+mx[now.dir];
int ny=now.y+my[now.dir];
if(dp[nx][ny][now.dir^]>dp[NOW]+){
dp[nx][ny][now.dir^]=dp[NOW]+;
if(!inq[nx][ny][now.dir^]){
inq[nx][ny][now.dir^]=;
nq.push((Node2){nx,ny,now.dir^});
}
}
}
int ans=INF;
for(int i=;i<;i++)ans=min(ans,dp[tx][ty][i]);
if(ans==INF)ans=-;
return ans;
}
int main(){
memset(mv,0x3f,sizeof(mv));
scanf("%d%d%d",&n,&m,&q);
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)scanf("%d",&g[i][j]);
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)if(g[i][j])
for(int k=;k<;k++)bfs1(i,j,k);
while(q--){
scanf("%d%d%d%d%d%d",&ex,&ey,&sx,&sy,&tx,&ty);
bfs2();
if(sx==tx&&sy==ty)printf("0\n");
else printf("%d\n",spfa());
}
return ;
}
LOJ2613 NOIP2013 华容道 【最短路】*的更多相关文章
- [NOIP2013]华容道 题解
[NOIP2013]华容道 首先是一种比较显然的做法. 整个棋盘,除了起点,终点和空格,其他的方块是等价的. 对于终点,它始终不会变化,如果搜到终点结束搜索即可,所以我们不需要考虑终点. 所以需要考虑 ...
- [NOIP2013]华容道 题解(搜索)
[NOIP2013]华容道 [题目描述] 这道题根据小时候玩华容道不靠谱的经验还以为是并查集,果断扑街.考后想想也是,数据这么小一定有他的道理. 首先由于是最小步数,所以BFS没跑了.那么我们大可把这 ...
- loj2613 「NOIP2013」华容道[最短路]
感觉和以前做过的一个推箱子很像,都是可以用bfs解决的,而且都是手玩出结论. 因为起始棋子肯定是要和空格交换的,所以第一件事是先把空格移到棋子旁边.然后讨论怎么设计搜索状态.由于和推箱子实在太像了,所 ...
- NOIP2013 华容道 (棋盘建图+spfa最短路)
#include <cstdio> #include <algorithm> #include <cstring> #include <queue> # ...
- JZYZOJ1442 [noip2013]华容道 bfs 最短路 剪枝
http://172.20.6.3/Problem_Show.asp?id=1442 想到最短路的简直神了,如果我写我大概只能写一个30分的bfs. 从数据范围可以看出思路是bfs剪枝,但这里的剪枝是 ...
- vijos1846 [NOIP2013] 华容道【最短路】
传送门:https://vijos.org/p/1983 (其实noip的题各个oj都会有的,就不贴其它传送门了) 这道题真的是,怎么说,我都不知道怎么评价了= =.果然数据量小的题怎么暴力都可以过. ...
- [NOIP2013]华容道
1.题面 小 B 最近迷上了华容道,可是他总是要花很长的时间才能完成一次.于是,他想到用编程来完成华容道:给定一种局面,华容道是否根本就无法完成,如果能完成,最少需要多少时间.小 B 玩的华容道与经典 ...
- NOIP2013华容道 大爆搜
预处理出每个点周围四个点互相到达的最短路,再在整个图上跑SPFA,要记录路径 #include<cstdio> #include<cstring> #include<io ...
- luogu P1979 [NOIP2013] 华容道
传送门 这道题中,棋子的移动是要移动到空格上去,所以空格要在棋子旁边才能移动棋子;而棋子移动的方向由空格决定 所以我们可以记三维状态\(di_{i,j,k}\),表示状态为棋子在\((i,j)\),空 ...
随机推荐
- HttpServletRequest request方法详解
//1.获取请求参数 //获取参数的单个值,如有多个则只返回第一个 String parameter1 = request.getParameter("demo"); //获取参数 ...
- codevs 1540 银河英雄传说 并查集
1540 银河英雄传说 2002年NOI全国竞赛 时间限制: 1 s 空间限制: 256000 KB 题目描述 Description 公元五八○一年,地球居民迁移至金牛座α第二行星, ...
- hiho 1318 非法二进制数 dp
#1318 : 非法二进制数 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 如果一个二进制数包含连续的两个1,我们就称这个二进制数是非法的. 小Hi想知道在所有 n 位 ...
- (转)SQL一次性插入大量数据
在SQL Server 中插入一条数据使用Insert语句,但是如果想要批量插入一堆数据的话,循环使用Insert不仅效率低,而且会导致SQL一系统性能问题.下面介绍SQL Server支持的两种批量 ...
- yii2打印数据属性(字段名)/数据
yii2打印数据属性(字段名)/数据 单条数据: $model = $this->findModel($id);//打印字段名 $array = $model->attributes(); ...
- kotlin for android----------MVP模式下(OKHttp和 Retrofit+RxJava)网络请求的两种实现方式
今天要说的干货是:以Kotlin,在MVP模式下(OKHttp和 Retrofit+RxJava)网络请求两种实现方式的一个小案例,希望对大家有所帮助,效果图: Retrofit是Square公司开发 ...
- 设计模式--享元模式C++实现
1定义 使用共享对象可有效的支持大量细粒度的对象 2类图 角色分析 Flyweight抽象享元角色,一个产品的抽象,定义内部状态和外部状态的接口或者实现 ConcreteFlyweight具体享元角色 ...
- SpringMvc+mybatis mybatis在xml文件中大于小于号处理
方法一:转移字符 用了转义字符把>和<替换掉,然后就没有问题了. SELECT * FROM test WHERE = AND start_date <= CURRENT_DATE ...
- JAVA执行带参数的SQL语句
转自 http://www.cnblogs.com/raymond19840709/archive/2008/05/12/1192948.html
- [nodejs]npm国内npm安装nodejs modules终极解决方案
此方案用于设置代理和修改镜像地址都不能解决问题使用 1.npm root 确认node模块的根文件夹,全局要加-g. osx同样是此命令,先清除缓存. npm cache clean C:\Users ...