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. HtmlAgilityPach基本使用方法

    //过滤html标签 static void InnerText() { HtmlWeb htmlWeb = new HtmlWeb(); HtmlDocument doc = htmlWeb.Loa ...

  2. DNS和Bind配置指南

    /////////////////////////////目录//////////////////////////////////////一.DNS原理相关二.使用bind搭建最简单的DNS服务器三. ...

  3. JavaScript内存泄漏知多少?

    垃圾回收解放了我们,它让我们可将精力集中在应用程序逻辑(而不是内存管理)上.但是,垃圾收集并不神奇.了解它的工作原理,以及如何使它保留本应在很久以前释放的内存,就可以实现更快更可靠的应用程序.在本文中 ...

  4. 前端构建大法 Gulp 系列

    参考: 前端构建大法 Gulp 系列 (一):为什么需要前端构建 前端构建大法 Gulp 系列 (二):为什么选择gulp 前端构建大法 Gulp 系列 (三):gulp的4个API 让你成为gulp ...

  5. [Eclipse]保存java文件时,自动删除不需要的包import

    1.修改设定:Window->Preferences 2.效果:                =>           

  6. panda2

    pandas是python为数据分析建造的可靠工具,很多地方和R语言有想通之处.数据分析并不是工具越高深越好,excel,R,python都是针对不同情况的不同工具,各有各的优缺点,就像你要搭一个架子 ...

  7. python脚本6_打印菱形

    #输入菱形最宽的行所在的行数,打印菱形 m = int(input(">>>")) for n in range(m): print(" "* ...

  8. [Tomcat 部署问题] Undeployment Failure could not be redeployed ...

    Tomcat 部署,在部署可能会出现以下问题: Deployment failure on Tomcat 6.x. Could not copy all resources to E:\apache- ...

  9. 【原创】移动端获取用户公网ip,获取用户ip

    有时候某些api需要获取用户的ip , 特此分享一下获取用户公网ip的方法 纯js <script src="http://pv.sohu.com/cityjson?ie=utf-8& ...

  10. JavaScript数字和字符串转换示例

    http://www.jb51.net/article/48465.htm 1. 数字转换为字符串 a. 要把一个数字转换为字符串,只要给它添加一个空的字符串即可: 复制代码代码如下: var n = ...