BZOJ 2464 小明的游戏
来源:互联网 发布:php取数组中的最大值 编辑:程序博客网 时间:2024/05/22 00:44
2464: 中山市选[2009]小明的游戏
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 829 Solved: 338
[Submit][Status][Discuss]
Description
小明最近喜欢玩一个游戏。给定一个n * m的棋盘,上面有两种格子#和@。游戏的规则很简单:给定一个起始位置和一个目标位置,小明每一步能向上,下,左,右四个方向移动一格。如果移动到同一类型的格子,则费用是0,否则费用是1。请编程计算从起始位置移动到目标位置的最小花费。
Input
输入文件有多组数据。
输入第一行包含两个整数n,m,分别表示棋盘的行数和列数。
输入接下来的n行,每一行有m个格子(使用#或者@表示)。
输入接下来一行有四个整数x1, y1, x2, y2,分别为起始位置和目标位置。
当输入n,m均为0时,表示输入结束。
Output
对于每组数据,输出从起始位置到目标位置的最小花费。每一组数据独占一行。
Sample Input
2 2
@#
#@
0 0 1 1
2 2
@@
@#
0 1 1 0
0 0
@#
#@
0 0 1 1
2 2
@@
@#
0 1 1 0
0 0
Sample Output
2
0
0
HINT
对于100%的数据满足:1 < = n, m <= 500。
一道最短路的模板题,瓶颈在于如何将二维节点建图,所以采取给节点编号的方式,每一个点[i,j]的编号对应为(i-1)*n+j.
#include<cstdio>#include<cstring>#include<string>#include<algorithm>#include<iostream>#include<cmath>#include<queue>#include<cstdlib>#define INF 1000000000using namespace std;const int MAXN=1010;const int MAXQ=255000;struct edge{int next,to,val;};edge e[MAXN*MAXN*4];int head[MAXN*MAXN],cnt;char a[MAXN][MAXN];const int dx[4]={-1,0,1,0};const int dy[4]={0,1,0,-1};void addedge(int u,int v,int w){e[++cnt].next=head[u];e[cnt].to=v;e[cnt].val=w;head[u]=cnt;}bool inqueue[MAXN*MAXN];int dis[MAXN*MAXN];int n,m;int q[MAXQ];void spfa(int s){for (int i=1;i<=n*m;i++){dis[i]=INF;}int l=0,r=1;q[1]=s;inqueue[s]=1;dis[s]=0; while (l!=r){l++;if (l==MAXQ){l=0;}int x=q[l];for (int i=head[x];i;i=e[i].next){if (dis[x]+e[i].val<dis[e[i].to]){dis[e[i].to]=dis[x]+e[i].val;if (!inqueue[e[i].to]){r++;if (r==MAXQ){r=0;}q[r]=e[i].to;inqueue[e[i].to]=1;}}}inqueue[x]=0;}}int main(){scanf("%d%d",&n,&m);while (n!=0 || m!=0){memset(head,0,sizeof(head));cnt=0;for (int i=1;i<=n;i++){char c[510];scanf("%s",c+1);for (int j=1;j<=m;j++){a[i][j]=c[j];}}for (int i=1;i<=n;i++){for (int j=1;j<=m;j++){char b=a[i][j];for (int k=0;k<4;k++){int nx=i+dx[k],ny=j+dy[k];if (nx>n || ny>m || nx<=0 || ny<=0){continue;}int pos=(i-1)*m+j;pos+=dx[k]*m;pos+=dy[k];if (a[nx][ny]==b){addedge((i-1)*m+j,pos,0);}else{addedge((i-1)*m+j,pos,1);}}}}int x1,y1,x2,y2;scanf("%d%d%d%d",&x1,&y1,&x2,&y2);spfa((x1)*m+y1+1);printf("%d\n",dis[(x2)*m+y2+1]); scanf("%d%d",&n,&m);} return 0;}
一种优化:提前开一个数组g[i,j],记录每一个点对应的坐标,这样在读入时只需要开一个cnt变量,读进来一个数就cnt++,对应的一定是这个点的编号。
阅读全文
0 0
- BZOJ 2464 小明的游戏
- BZOJ 2464 中山市选2009 小明的游戏 SPFA
- BZOJ 2464: 中山市选[2009]小明的游戏
- BZOJ 2464 中山市选[2009]小明的游戏 SPFA
- BZOJ[2464]中山市选[2009]小明的游戏 SPFA
- bzoj 2464 中山市选[2009]小明的游戏
- BZOJ 2464 中山市选 2009 小明的游戏 最短路
- bzoj 2464: 中山市选[2009]小明的游戏 最短路
- BZOJ 2464: 中山市选[2009]小明的游戏 简单搜索
- [BZOJ]1022 小约翰的游戏
- BZOJ 1022: [SHOI2008]小约翰的游戏John
- BZOJ 1022 SHOI2008 小约翰的游戏John 博弈论
- 【BZOJ 1022】 [SHOI2008]小约翰的游戏John
- BZOJ 1022 [SHOI2008]小约翰的游戏John
- BZOJ 1022 [SHOI2008]小约翰的游戏John
- BZOJ 小约翰的游戏John 反尼姆博弈
- bzoj 1022: [SHOI2008]小约翰的游戏John 博弈论
- 【BZOJ 1022】 [SHOI2008]小约翰的游戏John
- centos6.5之虚拟机 10连接SecureCRT 7.3
- freecodecamp项目---tictactoe
- 题目1534:数组中第K小的数字
- PAT乙级 1040. 有几个PAT(25)
- Android 自动化测试 Espresso篇:简介&基础使用
- BZOJ 2464 小明的游戏
- 页面中应用CSS的几种方式
- 我的第一个博客,致敬Java Hello Word
- Linux的chattr与lsattr命令详解
- PAT乙级 1041. 考试座位号(15)
- python实现贝叶斯分类器
- spring事务管理
- 事件的分发机制(总结)
- RSA密钥生成方式