【noip 2014】提高组Day2T3.华容道
Description
小 B 最近迷上了华容道,可是他总是要花很长的时间才能完成一次。于是,他想到用编程来完成华容道:给定一种局面,华容道是否根本就无法完成,如果能完成,最少需要多少时间。
小 B 玩的华容道与经典的华容道游戏略有不同,游戏规则是这样的:
1.在一个 n*m 棋盘上有 n*m 个格子,其中有且只有一个格子是空白的,其余 n*m-1个格子上每个格子上有一个棋子,每个棋子的大小都是 1*1 的;
2.有些棋子是固定的,有些棋子则是可以移动的;
3.任何与空白的格子相邻(有公共的边)的格子上的棋子都可以移动到空白格子上。 游戏的目的是把某个指定位置可以活动的棋子移动到目标位置。
给定一个棋盘,游戏可以玩 q 次,当然,每次棋盘上固定的格子是不会变的,但是棋盘上空白的格子的初始位置、指定的可移动的棋子的初始位置和目标位置却可能不同。第 i 次玩的时候,空白的格子在第EXi行EYi列,指定的可移动棋子的初始位置为第SXi行第SYi 列,目标位置为第TXi 行第TYi列。
假设小 B 每秒钟能进行一次移动棋子的操作,而其他操作的时间都可以忽略不计。请你告诉小 B 每一次游戏所需要的最少时间,或者告诉他不可能完成游戏。
Input
第一行有 3 个整数,每两个整数之间用一个空格隔开,依次表示 n、m 和 q;
接下来的 n 行描述一个 n*m 的棋盘,每行有 m 个整数,每两个整数之间用一个空格隔开,每个整数描述棋盘上一个格子的状态,0 表示该格子上的棋子是固定的,1 表示该格子上的棋子可以移动或者该格子是空白的。
接下来的 q 行,每行包含 6 个整数依次是EXi、EYi、SXi、SYi、TXi、TYi,每两个整数之间用一个空格隔开,表示每次游戏空白格子的位置,指定棋子的初始位置和目标位置。
Output
输出有 q 行,每行包含 1 个整数,表示每次游戏所需要的最少时间,如果某次游戏无法完成目标则输出−1。
Sample Input
3 4 2
0 1 1 1
0 1 1 0
0 1 0 0
3 2 1 2 2 2
1 2 2 2 3 2
Sample Output
2
-1
讲道理,这题的预处理真的不是来恶心人的吗TAT
然后有一个小技巧:用1代表上,2代表左,3代表右,4代表下,则a的反方向就是5-a。
存一存代码。
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
const int inf=0x3f3f3f3f;
int n,m,k,ex,ey,sx,sy,tx,ty,ans;
int map[][],deep[][],dis[][][],mov[][][][];
bool d[][],in[][][];
struct node{int x,y,k;}t1,t2;
int read()
{
int x=,f=;char c=getchar();
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
}
node move(node t,int k)
{
if(k==)t.x--;if(k==)t.y--;
if(k==)t.y++;if(k==)t.x++;
return t;
}
int bfs(node s,node t)
{
node now,to;
memset(deep,0x3f,sizeof(deep));
memset(d,,sizeof(d));
queue<node>q;q.push(s);
deep[s.x][s.y]=;d[s.x][s.y]=true;
while(!q.empty()&&!d[t.x][t.y])
{
now=q.front();q.pop();
for(int k=;k<=;k++)
{
to=move(now,k);
if(!d[to.x][to.y]&&map[to.x][to.y]==)
{
d[to.x][to.y]=true;q.push(to);
deep[to.x][to.y]=deep[now.x][now.y]+;
}
}
}
return deep[t.x][t.y];
}
void init()
{
memset(mov,0x3f,sizeof(mov));
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
{
if(map[i][j]==)continue;
map[i][j]=;
for(int k=;k<=;k++)
for(int l=;l<=;l++)
{
if(l<k){mov[i][j][k][l]=mov[i][j][l][k];continue;}
t1=move((node){i,j,k},k);t2=move((node){i,j,l},l);
if(map[t1.x][t1.y]==||map[t2.x][t2.y]==)continue;
mov[i][j][k][l]=bfs(t1,t2)+;
}
map[i][j]=;
}
}
void spfa(node s,node t)
{
ans=inf;
if(s.x==t.x&&s.y==t.y){ans=;return;}
if(map[s.x][s.y]==||map[t.x][t.y]==)return;
node now,to;
memset(dis,0x3f,sizeof(dis));
memset(in,,sizeof(in));
queue<node>q;
map[s.x][s.y]=;
for(int i=;i<=;i++)
{
q.push((node){s.x,s.y,i});
in[s.x][s.y][i]=true;
dis[s.x][s.y][i]=bfs((node){ex,ey,},move(s,i));
}
map[s.x][s.y]=;
while(!q.empty())
{
now=q.front();q.pop();
in[now.x][now.y][now.k]=false;
for(int i=;i<=;i++)
{
to=move(now,i);to.k=-i;
if(dis[now.x][now.y][now.k]+mov[now.x][now.y][now.k][i]<dis[to.x][to.y][-i])
{
dis[to.x][to.y][-i]=dis[now.x][now.y][now.k]+mov[now.x][now.y][now.k][i];
if(!in[to.x][to.y][to.k])q.push(to),in[to.x][to.y][to.k]=true;
}
}
}
for(int i=;i<=;i++)ans=min(ans,dis[t.x][t.y][i]);
}
int main()
{
n=read();m=read();k=read();
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
map[i][j]=read();
init();
for(int i=;i<=k;i++)
{
ex=read();ey=read();sx=read();sy=read();tx=read();ty=read();
spfa((node){sx,sy,},(node){tx,ty,});
if(ans==inf)printf("-1\n");
else printf("%d\n",ans);
}
return ;
}
【noip 2014】提高组Day2T3.华容道的更多相关文章
- NOIP 2014 提高组 题解
NOIP 2014 提高组 题解 No 1. 生活大爆炸版石头剪刀布 http://www.luogu.org/problem/show?pid=1328 这是道大水题,我都在想怎么会有人错了,没算法 ...
- noip 2014 提高组初赛
noip 2014 提高组初赛 一. TCP协议属于哪一层协议( ) A. 应用层 B. 传输层 C. 网络层 D. 数据链路层 B TCP(传输控制协议) 若有变量int a; float: x, ...
- noip 2014 提高组 Day 2
1.无线网络发射器选址 这道题数据范围很小,就直接暴力枚举就好了.为了提高速度,就从每个有公共场所的点枚举周围在(x,y)放无线网路发射器可以增加的公共场所数量,加到一个数组里.所有公共场所都处理完了 ...
- NOIP 2014 提高组 Day1
期望得分:100+100+50=250 实际得分:100+100+50=250 此次NOIP ZJ省一分数线:500,SD:345 https://www.luogu.org/problem/lis ...
- 洛谷P1979 [NOIP2013提高组Day2T3]华容道
P1979 华容道 题目描述 [问题描述] 小 B 最近迷上了华容道,可是他总是要花很长的时间才能完成一次.于是,他想到用编程来完成华容道:给定一种局面, 华容道是否根本就无法完成,如果能完成, 最少 ...
- NOIP 2014 提高组 Day2
期望得分:100+60+30=190 实际得分:70+60+30=160 https://www.luogu.org/problem/lists?name=&orderitem=pid& ...
- NOIP 2008提高组第三题题解by rLq
啊啊啊啊啊啊今天已经星期三了吗 那么,来一波题解吧 本题地址http://www.luogu.org/problem/show?pid=1006 传纸条 题目描述 小渊和小轩是好朋友也是同班同学,他们 ...
- [NOIp 1998 提高组]Probelm 2 连接多位数【2011百度实习生笔试题】
/*====================================================================== [NOIp 1998 提高组]Probelm 2 连接 ...
- NOIP 2001 提高组 题解
NOIP 2001 提高组 题解 No 1. 一元三次方程求解 https://vijos.org/p/1116 看见有人认真推导了求解公式,然后猥琐暴力过的同学们在一边偷笑~~~ 数据小 暴力枚举即 ...
随机推荐
- bzoj4481非诚勿扰(期望dp)
有n个女性和n个男性.每个女性的如意郎君列表都是所有男性的一个子集,并且可能为空.如果列表非空,她们会在其中选择一个男性作为自己最终接受的对象.将“如意郎君列表”中的男性按照编号从小到大的顺序呈现给她 ...
- 我眼中的 Docker(二)Image
Docker 安装 如何安装 docker 详见官网: installation 或者 中文指南. 不过 linux 上我推荐用 curl 安装,因为 apt-get 中源要么没有 docker,要么 ...
- ONI无法启动: Uh oh! Unable to launch Neovim...
问题描述 在终端中是可以打开nvim的,ONI无法正确找到位置 解决方法 修改配置文件,指定nvim的路径 终端中输入which nvim定位所在位置,这里返回的结果是/usr/local/bin/n ...
- 洛谷P3321 序列统计
气死了,FFT了半天发现是NTT... 1004535809 这个东西是NTT模数,原根为3. 题意:给定集合,元素的大小不超过M.用这些元素组成长为n的序列,要求乘积模M为k,求方案数. n < ...
- 团体程序设计天梯赛(CCCC) L3009 长城 方法证明
团体程序设计天梯赛代码.体现代码技巧,比赛技巧. https://github.com/congmingyige/cccc_code
- R语言绘图(FZ)
P-Value Central Lmit Theorem(CLT) mean(null>diff) hist(null) qqnorm(null) qqline(null) pops<-r ...
- ElasticSearch6.1.1集群搭建
其实早就想研究ES了,因为之前用solr,资料较少(这倒不是问题,有问题去官网读文档),貌似用的人比较少?(别打我)前几天去京东面试,我觉得有必要了解一下es,昨天晚上简单了解了官方文档,今天居然鼓捣 ...
- 免费馅饼 HDU - 1176 (动态规划)
都说天上不会掉馅饼,但有一天gameboy正走在回家的小径上,忽然天上掉下大把大把的馅饼.说来gameboy的人品实在是太好了,这馅饼别处都不掉,就掉落在他身旁的10米范围内.馅饼如果掉在了地上当然就 ...
- jQuery的on绑定事件在mobile safari(iphone / ipad / ipod)上无法使用的解决方案
用一个div当做了一个按钮来使用. <div class="button"> <div class=" next_button button_left ...
- (基础) 平方和与立方和 hdu2007
平方和与立方和 链接:http://acm.hdu.edu.cn/showproblem.php?pid=2007 Time Limit: 2000/1000 MS (Java/Others) ...