(noip 2013 华容道)<搜索>
来源:互联网 发布:js html传值 编辑:程序博客网 时间:2024/05/17 21:44
传送门
Solution
70分做法:
vis[x][y][kx][ky] 表示指定旗子在(x,y) ,空白格在(kx,ky) 的状态- 广搜就是移动空白格
- 当空白格移动到指定旗子的位置时,交换位置
- 队列中每个装态对应的步数是单调不降的,因此第一次走到目标位置就是最小步数
Code
// by spli#include<cstring>#include<cstdio>#include<algorithm>#include<iostream>#include<queue>using namespace std;int n,m,Q;bool can[35][35];int ex,ey,sx,sy,tx,ty;int mx[5]={0,1,0,-1,0};int my[5]={0,0,1,0,-1};bool vis[35][35][35][35];struct node{ int x,y,kx,ky,cnt;};queue<node>q;bool bfs(){ while(!q.empty()) q.pop(); vis[sx][sy][ex][ey]=1; q.push((node){sx,sy,ex,ey,0}); int x,y,kx,ky; while(!q.empty()){ node f=q.front(); q.pop(); for(int i=1;i<=4;++i){ x=f.x;y=f.y; kx=f.kx+mx[i]; ky=f.ky+my[i]; if(kx==x&&ky==y) x=f.kx,y=f.ky; if(!vis[x][y][kx][ky]&&x<=n&&x>=1&&y<=m&&y>=1&&can[x][y]&&can[kx][ky]){ vis[x][y][kx][ky]=1; if(x==tx&&y==ty){ printf("%d\n",f.cnt+1); return 1; } q.push((node){x,y,kx,ky,f.cnt+1}); } } } return 0;}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",&can[i][j]); while(Q--){ scanf("%d%d%d%d%d%d",&ex,&ey,&sx,&sy,&tx,&ty); memset(vis,0,sizeof(vis)); if(sx==tx&&sy==ty){ puts("0"); continue; } if(bfs()) continue; else puts("-1"); } return 0;}
满分做法:
- 把广搜的过程分成两个部分:①空白格移动到指定旗子的上下左右+②指定旗子移动到目标位置
- ①过程bfs解决
- ②:当指定旗子要从
(x,y) 移动到(x+1,y) 时,需要空白格先移动到(x+1,y) ,又因为此时空白格一定在(x,y) 上下左右的某个位置,而多次询问中,空白格从某个点上下左右不经过这个点的情况下到达这个点上下左右其它位置的步数是固定的,同样可以bfs预处理 - 因此②可以跑spfa,转移的代价就是预处理的步数
Code
// by spli#include<cstring>#include<cstdio>#include<algorithm>#include<iostream>#include<queue>using namespace std;const int inf=0x3f3f3f3f;int n,m,Q;bool can[35][35];int ex,ey,sx,sy,tx,ty;int mx[5]={0,1,0,-1};int my[5]={1,0,-1,0};int mv[35][35][5][5];int dis[35][35],d[35][35][5];bool vis[35][35][5];struct node{ int x,y,z;};queue<node>s,q;bool check(int x,int y){ if(x<1||x>n||y<1||y>m||!can[x][y]) return 0; return 1;}void bfs(int x,int y){ while(!s.empty()) s.pop(); while(!q.empty()) q.pop(); int kx,ky,px,py; node f; for(int i=0;i<4;++i){ kx=x+mx[i]; ky=y+my[i]; if(check(kx,ky)) s.push((node){kx,ky,i}); } while(!s.empty()){ memset(dis,0x3f3f3f3f,sizeof(dis)); f=s.front(); s.pop(); while(!q.empty()) q.pop(); q.push((node){f.x,f.y,f.z}); dis[f.x][f.y]=0; int z=f.z; while(!q.empty()){ node f=q.front(); q.pop(); px=f.x;py=f.y; for(int i=0;i<4;++i){ kx=px+mx[i]; ky=py+my[i]; if(check(kx,ky)&&dis[kx][ky]==inf&&(kx!=x||ky!=y)){ dis[kx][ky]=dis[px][py]+1; q.push((node){kx,ky,i}); } } } for(int i=0;i<4;++i){ kx=x+mx[i]; ky=y+my[i]; if(check(kx,ky)) mv[x][y][z][i]=dis[kx][ky]; } }}void pre(){ memset(dis,0x3f3f3f3f,sizeof(dis)); dis[ex][ey]=0; while(!q.empty()) q.pop(); q.push((node){ex,ey,0}); node f; int kx,ky,px,py; while(!q.empty()){ f=q.front(); q.pop(); px=f.x;py=f.y; for(int i=0;i<4;++i){ kx=px+mx[i]; ky=py+my[i]; if(check(kx,ky)&&(kx!=sx||ky!=sy)&&dis[kx][ky]==inf){ dis[kx][ky]=dis[px][py]+1; q.push((node){kx,ky,0}); } } }}void spfa(){ if(sx==tx&&sy==ty){ puts("0"); return; } node f; int kx,ky,px,py,z; memset(d,0x3f3f3f3f,sizeof(d)); memset(vis,0,sizeof(vis)); while(!q.empty()) q.pop(); for(int i=0;i<4;++i){ kx=sx+mx[i]; ky=sy+my[i]; if(check(kx,ky)&&dis[kx][ky]<inf){ q.push((node){sx,sy,i}); d[sx][sy][i]=dis[kx][ky]; vis[sx][sy][i]=1; } } while(!q.empty()){ f=q.front(); q.pop(); px=f.x;py=f.y;z=f.z; vis[px][py][z]=0; kx=px+mx[z]; ky=py+my[z]; if(d[kx][ky][(z+2)%4]>d[px][py][z]+1){ d[kx][ky][(z+2)%4]=d[px][py][z]+1; if(!vis[kx][ky][(z+2)%4]){ vis[kx][ky][(z+2)%4]=1; q.push((node){kx,ky,(z+2)%4}); } } for(int i=0;i<4;++i){ kx=px+mx[i]; ky=py+my[i]; if(check(kx,ky)&&i!=z&&d[px][py][i]>d[px][py][z]+mv[px][py][z][i]){ d[px][py][i]=d[px][py][z]+mv[px][py][z][i]; if(!vis[px][py][i]){ vis[px][py][i]=1; q.push((node){px,py,i}); } } } } int ans=inf; for(int i=0;i<4;++i) ans=min(ans,d[tx][ty][i]); if(ans>=inf) puts("-1"); else printf("%d\n",ans);}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",&can[i][j]); memset(mv,0x3f3f3f3f,sizeof(mv)); for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) if(can[i][j]) bfs(i,j); while(Q--){ scanf("%d%d%d%d%d%d",&ex,&ey,&sx,&sy,&tx,&ty); pre(); spfa(); } return 0;}
阅读全文
0 0
- (noip 2013 华容道)<搜索>
- 【noip】 华容道 搜索
- NOIP 2013 华容道(copy)
- [NOIP 2013]华容道
- [NOIP 2013] 华容道
- NOIP[2013] 华容道
- NKOJ 2498 (NOIP 2013)华容道(BFS+最短路)
- codevs 3290 noip 2013 Day2 T3华容道
- P1979 [NOIP]华容道
- P1979 [NOIP]华容道(70分的暴力)
- 华容道搜索算法研究
- 【NOIP2013】华容道 最短路优化搜索(spfa)
- 华容道游戏:广度优先搜索优先搜索
- 【浅析华容道之二】华容道问题搜索求解策略
- 华容道(Java Applet)
- 华容道
- 华容道
- 华容道
- js分几部分
- 【PAT】【Advanced Level】1110. Complete Binary Tree (25)
- 1005 number number number
- 重构二叉树
- jquery+bootstrap 实现简单备忘录(一)
- (noip 2013 华容道)<搜索>
- map大梗概
- Redis 和 Memcached 的区别
- linux 2.6升级Python2.7 ./configure 报错问题
- Spark算子讲解(一)
- 1008 transaction transaction transaction
- 将Sublime Text 3添加到右键菜单中
- 删除的聊天记录还能恢复!!聊天记录恢复方法汇总
- PBExcel导入