Codevs 1629 01迷宫

1629 01迷宫

时间限制: 1 s

空间限制: 256000 KB

题目等级 : 钻石 Diamond

题目描述 Description

有一个由01组成的n*n格迷宫,若你位于一格0上,那么你可以移动到相邻4格中的某一格1上,同样若你位于一格1上,那么你可以移动到相邻4格中的某一格0上。那么对于给定的迷宫,询问从某一格开始能移动到多少格。

输入描述 Input Description

输入的第1行为两个正整数n,m。

下面n行,每行n个字符,字符只可能是0或者1,字符之间没有空格。

接下来m行,每行2个用空格分隔的正整数i,j,对应了迷宫中第i行第j列的一个0,询问从这一格开始能移动到多少格。

输出描述 Output Description

输出包括m行,对于每个询问输出答案。

样例输入 Sample Input

2 2

01

10

1 1

2 2

样例输出 Sample Output

4

4

数据范围及提示 Data Size & Hint

【样例说明】

所有格子互相可达。

【数据规模】

对于20%的数据,n≤10;

对于40%的数据,n≤50;

对于50%的数据,m≤5;

对于60%的数据,n≤100,m≤100;

对于100%的数据,n≤1000,m≤1000000。

/*
bfs.
因为是多次查询.
so我们bfs把ans先记下来.
其实就是找联通快.
一开始没想到orz然后不会搜.
扩展点的数量就是队列中元素的数量.
*/
#include<iostream>
#include<cstdio>
#include<queue>
#include<cmath>
#define MAXN 1001
using namespace std;
int n,m,f[MAXN][MAXN],tot;
bool b[MAXN][MAXN],g[MAXN][MAXN];
struct node{int x,y;}s[MAXN*MAXN];
queue<node>q;
int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
return x*f;
}
void bfs(int x,int y)
{
tot=0;b[x][y]=true;
s[++tot].x=x,s[tot].y=y;
node u;
u.x=x,u.y=y;
q.push(u);
while(!q.empty())
{
u=q.front();q.pop();
x=u.x,y=u.y;
for(int i=-1;i<=1;i++)
for(int j=-1;j<=1;j++)
{
if(fabs(i+j)==1)
{
if(x+i>=1&&x+i<=n&&y+j>=1&&y+j<=n
&&!b[x+i][y+j]&&g[x][y]!=g[x+i][y+j])
{
b[x+i][y+j]=true;
s[++tot].x=x+i,s[tot].y=y+j;
node v;v.x=x+i,v.y=y+j;
q.push(v);
}
}
}
}
for(int i=1;i<=tot;i++)
f[s[i].x][s[i].y]=tot;
}
int main()
{
int x,y;
char ch;
n=read();m=read();
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
cin>>ch,g[i][j]=ch-48;
while(m--)
{
x=read(),y=read();
if(f[x][y]) printf("%d\n",f[x][y]);
else bfs(x,y),printf("%d\n",f[x][y]);
}
return 0;
}
上一篇:Web API 2 自定义默认Identity Table Name


下一篇:获取url中的参数\+发送ajax请求根路径|+获取复选框的值