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. 解决Eclipse Maven插件的最佳方案

    最近在尝试使用GAE,要求项目必须使用Maven,于是下载了Maven3.1.1配置了环境变量.但是在为Eclipse EE安装Maven插件的时候遇到了问题. 官网的建议是: 在Eclipse EE ...

  2. js原码工具集

    /* 原生js工具集 */ arr是否包含obj function contains1(arr, obj) { var i = arr.length; while (i--) { if (arr[i] ...

  3. form表单提交数据的数据格式

    form表单提交的数据格式默认是 enctype="application/x-www-form-urlencoded"这样将input框的数据与input框的name属性以键值对 ...

  4. winmm.dll获取和设置声音

    [DllImport("winmm.dll")] private static extern int waveOutGetVolume(IntPtr hwo, out uint d ...

  5. 【Demo】jQuery 轮播图简单动画效果

    功能实现: (1)设定图片称号的鼠标悬停事件: (2)在事件中利用自定义动画函数调整显示图片,并修改对应标号样式: (3)为图片显示区域设定鼠标悬停事件: (4)当鼠标停在该区域时,清除图片切换动画定 ...

  6. Android实现布局控件自定义属性

    一.自定义ViewGroup 1.onMeasure 决定内部View(子View)的宽度和高度,以及自己的宽度和高度 2.onLayout 决定子View放置的位置 3.onTouchEvent 定 ...

  7. Metasploit 使用简介

    Metasploit Framework 是非常优秀的开源渗透测试框架,像我这样的菜鸟刚刚听说,于是花时间好好研究了一下,整理了一下学习笔记,贴出来和大家一起交流.第一次写文章又不足的地方大家多多指点 ...

  8. 执行Maven install或Maven test命令时控制台输出乱码的解决办法

    [解决方案一] 在Maven的pom.xml文件中增加如下代码: <properties> <argLine>-Dfile.encoding=UTF-8</argLine ...

  9. Highcharts 测量图;Highcharts 圆形进度条式测量图;Highcharts 时钟;Highcharts 双轴车速表;Highcharts 音量表(VU Meter)

    Highcharts 测量图 配置 chart.type 配置 配置 chart 的 type 为 'gauge' .chart.type 描述了图表类型.默认值为 "line". ...

  10. 不使用构造方法创建Java对象: objenesis的基本使用方法

    转载:http://blog.csdn.net/codershamo/article/details/52015206 objenesis简介: objenesis是一个小型Java类库用来实例化一个 ...