NOIP2013 华容道

图论好题。 介于网上全是些令蒟蒻头昏的题解和排版一塌糊涂以及过于详细的题解。。。蒟蒻记录一下。。

显然需要将白格移动到 \(s\) 相邻格,然后交换 \(s\) 与白格,再将白格移动到 \(s\) 相邻格,然后交换 \(s\) 与白格……最后一步将白格移动到 与 \(s\) 相邻的 \(t\) ,交换白格与 \(s\)。

我们考虑到,将格子 \(a\) 从 \((i,j)\) 移动到相邻的格子 \(b\),需要让白格先移动到 \(b\),之后交换 \(a\) 与白格。显然 \(a\) 下一步还是要继续往其他方向移动的,所以白格仍然需要移动到格子 \(a\) 的某个相邻格。

我们写了一个 bfs ,可以在白格在 \((ei,ej)\), s \((si,sj)\) 的时候处理一些值,接下来详细阐述。


现在所阐述的 bfs 是在代码中 \(k=0,1,2,3\) 时的 bfs ,用于预处理建图。

设置状态 \((i,j,k)\) 表示 格子 \(s\) 在 \((i,j)\) ,白格在 \((i,j)\) 的方向 \(k\) 处。( \(k\) : left right up down,用0,1,2,3表示)。

可以通过 bfs 计算出 状态 \((i,j,k)\) 时, 白格开始移动,移动到棋盘上任意一个格子 \((x,y)\) 的花费 \(dis_{x,y}\)。注意,在代码中,为了方便标记哪些是不可能移动到的点,将所有 \(dis_{x,y}\) 都加一了,但在题解中 \(dis_{x,y}\) 仍然是原先的值。

从状态 \((i,j,k)\) 转移到另一个状态,有两种情况。

  • 白格与 \(s\) 交换,在状态 \((si,sj,k)\) 与 \((ei,ej,k\and 1)\) 之间连边 1。
  • 白格移动到了一个与 \(s\) 相邻的位置 \((xx,yy)\) ,在状态 \((si,sj,k)\) 与状态 \((si,sj,i)\) 之间连边 \(dis_{xx,yy}\).

如果要计算状态 \((x1,y1,k1)\) 到状态 \((x2,y2,k2)\) 之间的最小花费,只需要跑最短路即可。

也就是说,我们把状态作为点,花费作为边建图。


现在阐述的是在代码中 \(k=4\) 时的 bfs,这是处理 白格到 初始格的相邻格 花费的 bfs。

仍然先处理出所有的 \(dis_{x,y}\) , 意义与求法同 \(k=0,1,2,3\) 时一样。将与 \(s\) 相邻格的 \(dis_{x,y}\) 赋值在 dist 上。

最后计算答案,只需要 spfa 计算 \((tx,ty,0/1/2/3)\) 到 \((sx,sy,0/1/2/3)\) 的最短路。

#include<bits/stdc++.h>
using namespace std;
const int N=35,M=4010;
int n,m,q,mp[N][N],dis[N][N],dist[M];
bool vis[M];
int e,to[M*5],nxt[M*5],val[M*5],hd[M];
int dx[5]={-1,1,0,0};
int dy[5]={0,0,-1,1};
void add(int x,int y,int w){ to[++e]=y; nxt[e]=hd[x]; val[e]=w; hd[x]=e; }
void bfs(int ei,int ej,int si,int sj,int dir){
memset(dis,0,sizeof(dis));
queue<pair<int,int> >q;
q.push(make_pair(ei,ej)); dis[ei][ej]=1;
while(!q.empty()){
pair<int,int>w=q.front(); q.pop();
int x=w.first,y=w.second;
for(int i=0;i<4;i++){
int xx=x+dx[i],yy=y+dy[i];
if(!mp[xx][yy]||dis[xx][yy]||xx==si&&yy==sj) continue;
dis[xx][yy]=dis[x][y]+1; q.push(make_pair(xx,yy));
}
}//白格向外疯狂移动处理步数
if(dir==4) return; for(int i=0;i<4;i++){
int xx=si+dx[i],yy=sj+dy[i];
if((xx==ei&&yy==ej)||!dis[xx][yy]) continue;
add(si*30*4+sj*4+dir,si*30*4+sj*4+i,dis[xx][yy]-1);//白格移动
}
add(si*30*4+sj*4+dir,ei*30*4+ej*4+(dir^1),1);//交换
return;
}
void spfa(int x,int y){
memset(dist,0x3f,sizeof(dist));
memset(vis,0,sizeof(vis)); queue<int>q;
for(int i=0;i<4;i++){
if(!dis[x+dx[i]][y+dy[i]]) continue;
int id=x*30*4+y*4+i; q.push(id);
dist[id]=dis[x+dx[i]][y+dy[i]]-1; vis[id]=1;
}
while(!q.empty()){
int id=q.front(); q.pop(); vis[id]=0;
// cout<<id<<endl;
for(int i=hd[id];i;i=nxt[i]){
int nxid=to[i],nxval=val[i];
// cout<<"nxid: "<<nxid<<endl;
if(dist[nxid]>dist[id]+nxval){
dist[nxid]=dist[id]+nxval;
if(vis[nxid]) continue;
vis[nxid]=1; q.push(nxid);
}
}
}
return;
}
int main(){
scanf("%d%d%d",&n,&m,&q);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%d",&mp[i][j]);
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(!mp[i][j]) continue;
if(mp[i-1][j]) bfs(i-1,j,i,j,0);
if(mp[i+1][j]) bfs(i+1,j,i,j,1);
if(mp[i][j-1]) bfs(i,j-1,i,j,2);
if(mp[i][j+1]) bfs(i,j+1,i,j,3);
}
}
//预处理,建图
while(q--){
int ex,ey,sx,sy,tx,ty;
scanf("%d%d%d%d%d%d",&ex,&ey,&sx,&sy,&tx,&ty);
if(sx==tx&&sy==ty){ puts("0"); continue; } bfs(ex,ey,sx,sy,4); spfa(sx,sy); int ans=0x3f3f3f3f;
for(int i=0;i<4;i++) ans=min(ans,dist[tx*30*4+ty*4+i]);
(ans==0x3f3f3f3f)?puts("-1"):printf("%d\n",ans);
}
return 0;
}

[ NOIP2013 D2-T3 ] 华容道的更多相关文章

  1. [NOIP2016]愤怒的小鸟 D2 T3 状压DP

    [NOIP2016]愤怒的小鸟 D2 T3 Description Kiana最近沉迷于一款神奇的游戏无法自拔. 简单来说,这款游戏是在一个平面上进行的. 有一架弹弓位于(0,0)处,每次Kiana可 ...

  2. [NOIP2015]运输计划 D2 T3 LCA+二分答案+差分数组

    [NOIP2015]运输计划 D2 T3 Description 公元2044年,人类进入了宇宙纪元. L国有n个星球,还有n-1条双向航道,每条航道建立在两个星球之间,这n-1条航道连通了L国的所有 ...

  3. [NOIP2013 提高组] 华容道 P1979 洛谷

    [NOIP2013 提高组] 华容道 P1979 洛谷 强烈推荐,更好的阅读体验 经典题目:spfa+bfs+转化 题目大意: 给出一个01网格图,和点坐标x,y空格坐标a,b,目标位置tx,ty要求 ...

  4. [NOIP2016]愤怒的小鸟 D2 T3

    Description Kiana最近沉迷于一款神奇的游戏无法自拔. 简单来说,这款游戏是在一个平面上进行的. 有一架弹弓位于(0,0)处,每次Kiana可以用它向第一象限发射一只红色的小鸟,小鸟们的 ...

  5. NOIP2013 D1 T3 货车运输

    好吧,遇上这种题,作为蒟蒻的我第一个想到的就是怎么打暴力,然而暴力都打不好QAQ!!!于是只能等教练讲解以后,然后在大犇的指导下终于做出来了. 对了,,好像还,没上题....: 题目描述 A 国有 n ...

  6. 洛谷1967货车运输 即 NOIP2013 DAY1 T3

    题目描述 A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物, 司机们想知道每辆车在不超过车辆限重的情况下,最多 ...

  7. NOIP2013 DAY2 T3火车运输

    传送门 题目描述 A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物, 司机们想知道每辆车在不超过车辆限重的情况 ...

  8. 逛公园[NOIP2017 D2 T3](dp+spfa)

    题目描述 策策同学特别喜欢逛公园. 公园可以看成一张 \(N\)个点\(M\) 条边构成的有向图,且没有自环和重边.其中 1号点是公园的入口,N号点是公园的出口,每条边有一个非负权值,代表策策经过这条 ...

  9. NOIP2012 D2 T3 疫情控制 洛谷P1084

    题目链接:https://www.luogu.org/problemnew/show/P1084 算法:倍增,二分答案,贪心 + 瞎搞.. 背景:上学长的数论课啥也听不懂,于是前去提高组找安慰.不巧碰 ...

  10. [NOIP2013提高组]华容道

    这道题第一眼看是暴力,然后发现直接暴力会TLE. 把问题转换一下:移动空格到处跑,如果空格跑到指定位置的棋子,交换位置. 这个可以设计一个状态:$[x1][y1][x2][y2]$,表示空格在$(x1 ...

随机推荐

  1. AntDesign VUE:上传组件自定义限制的两种方式(Boolean、Promise)

    AntD上传组件 AntDesign VUE文档 第一种方式 beforeUpload(file) { let isLt = true if (filesSize) { isLt = file.siz ...

  2. (4)java Spring Cloud+Spring boot+mybatis企业快速开发架构之SpringCloud-Spring Cloud开发环境的准备和Lombok安装步骤

    ​ 开发环境的准备主要涉及三个方面:JDK.Maven.Spring Tools 4 for Eclipse. 1.JDK JDK 的版本用 1.8 即可,环境变量大家自行去配置.配置好环境变量,在命 ...

  3. 使用PHP获取图像文件的EXIF信息

    在我们拍的照片以及各类图像文件中,其实还保存着一些信息是无法直观看到的,比如手机拍照时会有的位置信息,图片的类型.大小等,这些信息就称为 EXIF 信息.一般 JPG . TIFF 这类的图片文件都会 ...

  4. 网页兼容最新IE声明meta方法

    第三种,总是使用最新版本文档模式. 以下是例子: <meta http-equiv="X-UA-Compatible" content="IE=edge" ...

  5. disruptor笔记之一:快速入门

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  6. pip3 install beautifulsoup4 出现错误 There was a problem confirming the ssl certificate

    chenhuimingdeMacBook-Pro:groceryList Mch$ sudo pip3 install beautifulsoup4 The directory '/Users/Mch ...

  7. Appium driver常用API

    click driver.find_element implicitly_wait send_keys close quit get_window_size switch_to execute bac ...

  8. Redis-Cluster分片扩容

    redis分片分片场景在业务量相对较小的时候,可以将所有数据都存到一台机器上,只使用redis单机模式,不存在分片问题.如果业务的数据量超过一台物理机器的内存大小时,则会面对扩展问题,需要多台机器去存 ...

  9. c++ 的学习笔记 第一集cim cout

    1. 你要用这个东西,所以得有包含它得头文件,就像java 你要用某个模块,你得包含这个模块 模块化??单片机里面学的模块化(可以在vs里面实现) 2. 当我把注册表regedit 程序删除之后成功了 ...

  10. Dapr + .NET Core实战(七)Secrets

    什么是Secrets 应用程序通常会通过使用专用的存储来存储敏感信息,如连接字符串.密钥等. 通常这需要建立一个密钥存储,如Azure Key Vault.Hashicorp等,并在那里存储应用程序级 ...