【NOIP2013】 华容道 bfs预处理+bfs
这一题我们考虑一个最裸的算法:
我们设$dp[i][j][k][l]$表示当前棋子在$(i,j)$且空格在$(k,l)$时的最小步数
然后显然随便转移一下就好了,时间复杂度为$O(q(nm)^2)$。可以获得$80$分的好成绩(我自测的时候只打了这个)
我们发现这一题有一些很优秀的性质:
首先整个图是静态的,且起点,终点,出现空格的位置均非障碍物。
那么对于这个性质,我们做一些微小的预处理。
考虑到当空格与目标棋子四相邻的时候,棋子才能往空格内移动。那么整个走棋的过程可以理解为:调整空格位置-移动棋子到空格里-调整空格位置
我们设$f[i][j][k][l]$表示在不经过$(i,j)$的情况下,将空格从$(i+wx[k],j+wy[k])$移动到$(i+wx[l],j+wy[l])$的最小步数,其中$wx,wy$满足$|wx[i]+wy[i]|=1$,显然有四种组合。
对于每一个$f[i][j][k][l]$,我们通过一次$bfs$去求解。
预处理$f$的时间复杂度显然为$O(16nm)$。
下面考虑每一组询问:
若起点和终点的坐标相同,那么显然输出$0$就好了。
若起点和终点坐标不相同,我们先考虑将空格移动到起点四相邻的位置,所需要的最小步数显然可以通过一次$bfs$求得。
然后我们设$d[i][j][k]$表示当前棋子在$(i,j)$时,空格在$(i+wx[k],j+wy[k])$的最小步数。
显然随便$bfs$就可以进行更新了。最后的答案显然是$min(d[tx][ty][])$。
时间复杂度$O(16nm+4qnm)$。跑得飞快。
#include<bits/stdc++.h>
#define M 32
#define INF 16843009
using namespace std;
int n,m,q,mp[M][M]={},dis[M][M]={},d[M][M][]={},f[M][M][][]={};
const int wx[]={,,,-};
const int wy[]={,,-,};
queue<int> qx,qy,qk;
void bfs(int X,int Y){
memset(dis,,sizeof(dis));
qx.push(X); qy.push(Y); dis[X][Y]=;
while(!qx.empty()){
X=qx.front(); qx.pop();
Y=qy.front(); qy.pop();
for(int i=;i<;i++){
int _x=X+wx[i],_y=Y+wy[i];
if(mp[_x][_y]&&dis[_x][_y]>dis[X][Y]+){
dis[_x][_y]=dis[X][Y]+;
qx.push(_x); qy.push(_y);
}
}
}
}
void move(int x,int y){
memset(dis,,sizeof(dis));
qx.push(x); qy.push(y); dis[x][y]=;
while(!qx.empty()){
x=qx.front(); qx.pop();
y=qy.front(); qy.pop();
for(int i=;i<;i++){
int _x=x+wx[i],_y=y+wy[i];
if(mp[_x][_y]&&dis[_x][_y]>dis[x][y]+){
dis[_x][_y]=dis[x][y]+;
qx.push(_x); qy.push(_y);
}
}
}
} void bfs(){
while(!qx.empty()){
int x=qx.front(); qx.pop();
int y=qy.front(); qy.pop();
int k=qk.front(); qk.pop();
for(int i=;i<;i++){
int _x=x+wx[i],_y=y+wy[i];
if(mp[_x][_y]==) continue;
if(d[_x][_y][(i+)&]>d[x][y][k]+f[x][y][k][i]+){
d[_x][_y][(i+)&]=d[x][y][k]+f[x][y][k][i]+;
qx.push(_x); qy.push(_y); qk.push((i+)&);
}
}
}
} int main(){
scanf("%d%d%d",&n,&m,&q);
for(int i=;i<=n;i++)
for(int j=;j<=m;j++) scanf("%d",&mp[i][j]); for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
if(mp[i][j]){
mp[i][j]=;
for(int k=;k<;k++)
if(mp[i+wx[k]][j+wy[k]]){
bfs(i+wx[k],j+wy[k]);
for(int l=;l<;l++)
f[i][j][k][l]=dis[i+wx[l]][j+wy[l]];
}
mp[i][j]=;
} while(q--){
int ex,ey,sx,sy,tx,ty;
cin>>ex>>ey>>sx>>sy>>tx>>ty;
if(sx==tx&&sy==ty){
printf("0\n");
continue;
}
mp[sx][sy]=;
move(ex,ey);
mp[sx][sy]=;
memset(d,,sizeof(d));
for(int i=;i<;i++)
if(mp[sx+wx[i]][sy+wy[i]]){
qx.push(sx);
qy.push(sy);
qk.push(i);
d[sx][sy][i]=dis[sx+wx[i]][sy+wy[i]];
}
bfs();
int minn=INF;
for(int i=;i<;i++)
minn=min(minn,d[tx][ty][i]);
if(minn==INF) printf("-1\n");
else cout<<minn<<endl;
}
}
【NOIP2013】 华容道 bfs预处理+bfs的更多相关文章
- BZOJ-1189 紧急疏散evacuate BFS预处理+最大流+二分判定+神建模!!
绝世污题,垃圾题,浪费我一整天青春! 1189: [HNOI2007]紧急疏散evacuate Time Limit: 10 Sec Memory Limit: 162 MB Submit: 1262 ...
- HDU - 1430 魔板 (bfs预处理 + 康托)
对于该题可以直接预处理初始状态[0, 1, 2, 3, 4, 5, 6, 7]所有可以到达的状态,保存到达的路径,直接打印答案即可. 关于此处的状态转换:假设有初始状态为2,3,4,5,0,6,7,1 ...
- 【2016 ICPC亚洲区域赛北京站 E】What a Ridiculous Election(BFS预处理)
Description In country Light Tower, a presidential election is going on. There are two candidates, ...
- HDU 3533 Escape(BFS+预处理)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3533 题目大意:给你一张n* m的地图,人在起点在(0,0)要到达终点(n,m)有k(k<=10 ...
- bzoj 1415(概率dp和bfs预处理)
感觉挺经典的一道题目. 先用 bfs 预处理下一步走到的位置.因为每一步走法都是固定的,所以可以用dp的方法来做. 1415: [Noi2005]聪聪和可可 Time Limit: 10 Sec M ...
- [NOIP2013]华容道 题解(搜索)
[NOIP2013]华容道 [题目描述] 这道题根据小时候玩华容道不靠谱的经验还以为是并查集,果断扑街.考后想想也是,数据这么小一定有他的道理. 首先由于是最小步数,所以BFS没跑了.那么我们大可把这 ...
- [NOIP2013]华容道 题解
[NOIP2013]华容道 首先是一种比较显然的做法. 整个棋盘,除了起点,终点和空格,其他的方块是等价的. 对于终点,它始终不会变化,如果搜到终点结束搜索即可,所以我们不需要考虑终点. 所以需要考虑 ...
- luogu P1979 [NOIP2013] 华容道
传送门 这道题中,棋子的移动是要移动到空格上去,所以空格要在棋子旁边才能移动棋子;而棋子移动的方向由空格决定 所以我们可以记三维状态\(di_{i,j,k}\),表示状态为棋子在\((i,j)\),空 ...
- LOJ2613 NOIP2013 华容道 【最短路】*
LOJ2613 NOIP2013 华容道 LINK 这是个好题,具体题意比较麻烦可以直接看LINK中的链接 然后考虑我们可能的移动方式 首先我们需要把白块移动到需要移动块S的附近(附近四格) 然后我们 ...
随机推荐
- 2018.10.15 bzoj3564: [SHOI2014]信号增幅仪(坐标处理+最小圆覆盖)
传送门 省选考最小圆覆盖? 亦可赛艇(你们什么都没看见) 在大佬的引领下成功做了出来. 就是旋转坐标使椭圆的横轴跟xxx轴平行. 然后压缩横坐标使得其变成一个圆. 然后跑最小覆盖圆就可以了. 注意题目 ...
- HDU 3247 Resource Archiver (AC自动机+BFS+状压DP)
题意:给定 n 个文本串,m个病毒串,文本串重叠部分可以合并,但合并后不能含有病毒串,问所有文本串合并后最短多长. 析:先把所有的文本串和病毒都插入到AC自动机上,不过标记不一样,可以给病毒标记-1, ...
- python文件对比
#-*- encoding:utf-8 -*- class loadDatas(object): def __init__(self): self.path='./data' def load_com ...
- 修改Python IDLE代码配色及语法高亮主题
初学Python,想必大家拿来练习最多的IDE就是Python自带的IDLE了,但是默认的代码配色及语法高亮主题确实很不适应,所以我们需要做个小小的美化,比如像下面这样我做的美化配置: HOW TO ...
- “无后端”的web应用开发模式
最近看到前端趋势2013大会上的一篇文章,题目是<各位快看,不用后端>,觉得有点意思,恰好近期的一次讨论及半年前的一次开发实践也涉及到这种模式,简单谈谈我的想法. 不得不说,文章的题目确实 ...
- Redis Cluster原理初步
目录 目录 1 1. 前言 1 2. 槽(slots) 1 3. 路由配置(node.conf) 1 4. 总slots数(cluster.h:16384) 2 5. key的路由 2 6. 将key ...
- New JVM Option Enables Generation of Mixed-Mode Flame Graphs
转自 https://www.infoq.com/news/2015/08/JVM-Option-mixed-mode-profiles Java has added a new launch opt ...
- Linux内存子系统及常用调优参数
1>内存子系统 1>组件: slab allocator buddy system kswapd pdflush 2>虚拟化环境: PA:进程地址: HA:虚拟机地址: ...
- Nonsense Alphabet
Nonsense Alphabet A was an ant Who seldom stood still, And who made a nice house In the side of a hi ...
- LINQ to XML基本操作
Linq to XML同样是对原C#访问XML文件的方法的封装,简化了用xpath进行xml的查询以及增加,修改,删除xml元素的操作. LINQ to XML 三个最重要类:XElement.XAt ...