LOJ2613 NOIP2013 华容道


LINK


这是个好题,具体题意比较麻烦可以直接看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 华容道 【最短路】*的更多相关文章

  1. [NOIP2013]华容道 题解

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

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

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

  3. loj2613 「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. [NOIP2013]华容道

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

  8. NOIP2013华容道 大爆搜

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

  9. luogu P1979 [NOIP2013] 华容道

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

随机推荐

  1. nginx web服务器详解1(转)

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://freeloda.blog.51cto.com/2033581/1285332 大 ...

  2. 关于java 线程池 ThreadPoolExceutor 之 TestDemo

    public class App { public static void main(String[] args) throws InterruptedException { System.out.p ...

  3. 从源码角度分析 Kotlin by lazy 的实现

    by lazy 的作用 延迟属性(lazy properties) 是 Kotlin 标准库中的标准委托之一,可以通过 by lazy 来实现. 其中,lazy() 是一个函数,可以接受一个 Lamb ...

  4. 什么情况下用resultType和 resultMap

    MyBatis中在查询进行select映射的时候,返回类型可以用resultType,也可以用resultMap 那什么情况下用resultType? resultMap 一般用在什么情况下?   如 ...

  5. 十八 Python分布式爬虫打造搜索引擎Scrapy精讲—Scrapy启动文件的配置—xpath表达式

    我们自定义一个main.py来作为启动文件 main.py #!/usr/bin/env python # -*- coding:utf8 -*- from scrapy.cmdline import ...

  6. php上传文件出现500错误

    问题: 能上传小于10k的文件,上传大于10k的文件就会报500错误 解决办法: 首先查看错误日志,看看报错是什么 其次查看client_body_temp的权限问题 关于client_body_te ...

  7. Ansible 小手册系列 九(Playbook)

    playbook是由一个或多个"play"组成的列表.play的主要功能在于将事先归并为一组的主机装扮成事先通过ansible中的task定义好的角色.从根本上来讲所谓task无非 ...

  8. (转)让IE6/IE7/IE8浏览器支持CSS3属性

    原文链接 http://blog.csdn.net/h5_queenstyle12/article/details/50437442 一.下载 搜索下载:ie-css3.htc,它是让IE浏览器支持C ...

  9. 005PHP基础知识——数据类型(二)

    <?php /** * 布尔型判断一种状态是否成立. * 布尔型 TRUE FALSE * 为布尔假型的类型: * 1. FALSE * 2. 0 * 3. 0.0 * 4. 空字符串为假 * ...

  10. 在js中做数字字符串补0

    转自(http://blog.csdn.net/aimingoo/article/details/4492592) 通常遇到的一个问题是日期的“1976-02-03 HH:mm:ss”这种格式 ,我的 ...