洛谷 P1979 华容道
来源:互联网 发布:最好的网络言情小说 编辑:程序博客网 时间:2024/05/15 12:47
题目描述
小 B 最近迷上了华容道,可是他总是要花很长的时间才能完成一次。于是,他想到用编程来完成华容道:给定一种局面, 华容道是否根本就无法完成,如果能完成, 最少需要多少时间。
小 B 玩的华容道与经典的华容道游戏略有不同,游戏规则是这样的:
在一个 n*m 棋盘上有 n*m 个格子,其中有且只有一个格子是空白的,其余 n*m-1个格子上每个格子上有一个棋子,每个棋子的大小都是 1*1 的;
有些棋子是固定的,有些棋子则是可以移动的;
任何与空白的格子相邻(有公共的边)的格子上的棋子都可以移动到空白格子上。
游戏的目的是把某个指定位置可以活动的棋子移动到目标位置。
给定一个棋盘,游戏可以玩 q 次,当然,每次棋盘上固定的格子是不会变的, 但是棋盘上空白的格子的初始位置、 指定的可移动的棋子的初始位置和目标位置却可能不同。第 i 次
玩的时候, 空白的格子在第 EXi 行第 EYi 列,指定的可移动棋子的初始位置为第 SXi 行第 SYi列,目标位置为第 TXi 行第 TYi 列。
假设小 B 每秒钟能进行一次移动棋子的操作,而其他操作的时间都可以忽略不计。请你告诉小 B 每一次游戏所需要的最少时间,或者告诉他不可能完成游戏。
【题目分析】
bfs+SPFA
【代码】
#include <cstdio>#include <cmath>#include <cstring>#include <queue>#include <iostream>#include <algorithm>using namespace std;const int inf=0x3f3f3f3f;int map[31][31];int hash[31][31][4],cnt=0;int mov[4][2]={{1,0},{-1,0},{0,1},{0,-1}}; int h[4000001],ne[4000001],to[4000001],w[4000001],en=0;int dis[3601],inq[3601];int vis[31][31];int n,m,que;int ex,ey,fx,fy,tx,ty;struct node{ int x,y; int step;};void add(int a,int b,int c){ to[en]=b; ne[en]=h[a]; w[en]=c; h[a]=en++;}int bfs(int fx,int fy,int tx,int ty,int bx,int by){ queue <node> q; while (!q.empty()) q.pop(); if (fx==tx&&fy==ty) return 0; memset(vis,0,sizeof vis); vis[fx][fy]=1; node now; now.x=fx,now.y=fy;now.step=0; q.push(now); while (!q.empty()) { node to; now=q.front();q.pop(); if (now.x==tx&&now.y==ty) return now.step; for (int i=0;i<4;++i) if (map[now.x+mov[i][0]][now.y+mov[i][1]]&&!vis[now.x+mov[i][0]][now.y+mov[i][1]]&&(now.x+mov[i][0]!=bx||now.y+mov[i][1]!=by)){ to.x=now.x+mov[i][0]; to.y=now.y+mov[i][1]; to.step=now.step+1; q.push(to); vis[to.x][to.y]=1; } } return inf;}int SPFA(int ex,int ey,int fx,int fy,int tx,int ty){ queue <int> q; if (fx==tx&&fy==ty) return 0; memset(dis,0x3f,sizeof dis); for (int i=0;i<4;++i) if (hash[fx][fy][i]) { dis[hash[fx][fy][i]]=bfs(ex,ey,fx+mov[i][0],fy+mov[i][1],fx,fy); q.push(hash[fx][fy][i]); inq[hash[fx][fy][i]]=1; } while (!q.empty()) { int x=q.front();q.pop();inq[x]=0; for (int i=h[x];i>=0;i=ne[i]) { if (dis[to[i]]>dis[x]+w[i]) { dis[to[i]]=dis[x]+w[i]; if (!inq[to[i]]) { q.push(to[i]); inq[to[i]]=1; } } } } int ans=inf; for (int k=0;k<4;++k) if (hash[tx][ty][k]) ans=min(ans,dis[hash[tx][ty][k]]); return ans==inf?-1:ans;}int main(){ memset(h,-1,sizeof h); scanf("%d%d%d",&n,&m,&que); for (int i=1;i<=n;++i) for (int j=1;j<=m;++j) scanf("%d",&map[i][j]); for (int i=1;i<=n;++i) for (int j=1;j<=m;++j) for (int k=0;k<4;++k) if (map[i][j]&&map[i+mov[k][0]][j+mov[k][1]]) hash[i][j][k]=++cnt; for (int i=1;i<=n;++i) for (int j=1;j<=m;++j) for (int k=0;k<4;++k) if (hash[i][j][k]) add(hash[i][j][k],hash[i+mov[k][0]][j+mov[k][1]][k^1],1); for (int i=1;i<=n;++i) for (int j=1;j<=m;++j) for (int k=0;k<4;++k) for (int l=0;l<4;++l) if (k!=l&&hash[i][j][k]&&hash[i][j][l]) add(hash[i][j][k],hash[i][j][l],bfs(i+mov[k][0],j+mov[k][1],i+mov[l][0],j+mov[l][1],i,j)); while (que--) { scanf("%d%d%d%d%d%d",&ex,&ey,&fx,&fy,&tx,&ty); printf("%d\n",SPFA(ex,ey,fx,fy,tx,ty)); }}
0 0
- 洛谷 P1979 华容道
- 洛谷 P1979 华容道
- [洛谷luogu] P1979 [NOIP2013T6]华容道
- 洛谷P1979 华容道(dfs)
- P1979 华容道
- [P1979]华容道
- [P1979]华容道
- P1979 [NOIP]华容道
- NOIP2013 D2T3 codevs 3290 洛谷 P1979 华容道 题解报告
- P1979 [NOIP]华容道(70分的暴力)
- 【NOIP2013】洛谷1979 华容道
- 华容道
- 华容道
- 华容道
- 华容道
- 华容道!
- 华容道
- 华容道
- [背包]poj1276 Cash Machine
- Linux 压缩命令 zip tar gzip bzip2
- 薪水不高,怎么投资自己?我是这么做的
- 【PS】黑白照片改为彩色照片
- 深入理解JAVA虚拟机之内存管理
- 洛谷 P1979 华容道
- Hive优化--关键参数配置指导
- 【PAT甲级】【C++】1007. Maximum Subsequence Sum (25)
- 宜信笔试题,很简单很基础,基本一次AC
- 用github来备份sublime配置
- 你真的了解单例模式吗?你真的认为单例模式很简单吗? 第一篇
- Hive优化--关键参数及HQL案例
- Qt: 网络编程实例,QNetworkAccessManager获取网页数据
- android stdio报Failed to resolve: junit:junit:4.12错误的解决方法