problem
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
Sample Output
2
0
Data Constraint
Hint
【数据规模】
对于20%的数据满足:1 < = n, m <= 10。
对于40%的数据满足:1 < = n, m <= 300。
对于100%的数据满足:1 < = n, m <= 500。
analysis
又是一道水题
每一个点向上下左右四个方向连一条0或1的边
然后上SPFA跑一遍最短路
我™就因为数组开小调了一个多半钟so stupid
code
#include<stdio.h>
#include<string.h>
#define MAXN 501
#define MAXM 250001
#define MAXLEN 1000001
using namespace std;
char a[MAXN][MAXN],flag[MAXM];
int last[2*MAXM],next[2*MAXM],tov[2*MAXM],dist[2*MAXM];
int num[MAXN][MAXN],dis[MAXM];
int queue[MAXLEN];
int n,m,x1,y1,x2,y2,tot;
int read()
{
int x=0,f=1;
char ch;
while(ch<'0'||ch>'9')
{
if(ch=='-')f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=x*10+ch-'0';
ch=getchar();
}
return f*x;
}
void insert(int x,int y,int z)
{
next[++tot]=last[x];
last[x]=tot;
tov[tot]=y;
dist[tot]=z;
}
int main()
{
//freopen("read.txt","r",stdin);
while ((n=read()) && (m=read()))
{
tot=0;
for (int i=1;i<=n;i++)
{
for (int j=1;j<=m;j++)
{
a[i][j]=getchar();
num[i][j]=++tot;
}
scanf("\n");
}
tot=0;
memset(last,0,sizeof(last));
memset(next,0,sizeof(next));
memset(tov,0,sizeof(tov));
memset(dist,0,sizeof(dist));
for (int i=1;i<n;i++)
{
for (int j=1;j<=m;j++)
{
int x=a[i][j]==a[i+1][j]?0:1;
insert(num[i][j],num[i+1][j],x);
insert(num[i+1][j],num[i][j],x);
}
}
for (int j=1;j<m;j++)
{
for (int i=1;i<=n;i++)
{
int x=a[i][j]==a[i][j+1]?0:1;
insert(num[i][j],num[i][j+1],x);
insert(num[i][j+1],num[i][j],x);
}
}
x1=read()+1,y1=read()+1,x2=read()+1,y2=read()+1;
memset(queue,0,sizeof(queue));
memset(flag,1,sizeof(flag));
memset(dis,0x7f,sizeof(dis)) ;
int head=0,tail=1;
queue[1]=num[x1][y1];
flag[num[x1][y1]]=0;
dis[num[x1][y1]]=0;
while (head!=tail)
{
int now=queue[head=head==MAXLEN?1:head+1];
if (now==num[x2][y2])
{
flag[now]=1;
continue;
}
for (int i=last[now];i;i=next[i])
{
int j=tov[i];
if (dis[now]+dist[i]<dis[j])
{
dis[j]=dis[now]+dist[i];
if (flag[j])
{
queue[tail=tail==MAXLEN?1:tail+1]=j;
flag[j]=0;
}
}
}
flag[now]=1;
}
printf("%d\n",dis[num[x2][y2]]);
}
return 0;
}