原来认为只是一道简单的BFS自信满满的提交了
5000多毫秒.....
题目描述
有一个仅由数字0与1组成的n×n格迷宫。若你位于一格0上,那么你可以移动到相邻4格中的某一格1上,同样若你位于一格1上,那么你可以移动到相邻4格中的某一格0上。
你的任务是:对于给定的迷宫,询问从某一格开始能移动到多少个格子(包含自身)。
输入输出格式
输入格式:输入的第1行为两个正整数n,m。
下面n行,每行n个字符,字符只可能是0或者1,字符之间没有空格。
接下来m行,每行2个用空格分隔的正整数i,j,对应了迷宫中第i行第j列的一个格子,询问从这一格开始能移动到多少格。
输出格式:输出包括m行,对于每个询问输出相应答案。
输入输出样例
说明
所有格子互相可达。
对于20%的数据,n≤10;
对于40%的数据,n≤50;
对于50%的数据,m≤5;
对于60%的数据,n≤100,m≤100;
对于100%的数据,n≤1000,m≤100000。
后来,看了讨论区发现时类似于并查集
本来就是联通问题,把搜到的每个点都记录一下他们的父亲节点(答案都是一样的)
#include<bits/stdc++.h>
using namespace std;
struct node
{
int x,y;
};
int n,m;
char mm[1005][1005];
int dx[4]={1,-1,0,0};
int dy[4]={0,0,-1,1};
int visx[1005][1005];//标记的同时记录扫过的点的父点横坐标
int visy[1005][1005];//记录父点的纵坐标
int ans[1005][1005];//记录该点的答案(其子点也可以查询)
int rootx,rooty;//记录根
queue<node >q;
bool judge(node a,node b)
{
if(a.x<1||a.x>n||a.y<1||a.y>n)return false;
if(b.x<1||b.x>n||b.y<1||b.y>n)return false;
if(mm[a.x][a.y]==mm[b.x][b.y])return false;
else return true;
}
int BFS(node b)
{
int as=1;
visx[rootx][rooty]=rootx;
visy[rootx][rooty]=rooty;
node t,t1;
q.push(b);
while(!q.empty())
{
t=q.front();
q.pop();
for(int i=0;i<4;i++)
{
t1.x=t.x+dx[i];
t1.y=t.y+dy[i];
if(judge(t,t1)&&visx[t1.x][t1.y]==0)
{
visx[t1.x][t1.y]=rootx;
visy[t1.x][t1.y]=rooty;
as++;
q.push(t1);
}
}
}
return as;
}
int main()
{
memset(ans,0,sizeof(ans));
//memset(visx,0,sizeof(visx));
scanf("%d%d",&n,&m);
char ch=getchar();
for(int i=1;i<=n;i++)
{
scanf("%s",mm[i]+1);
}
int x,y;
node a;
int t;
while(m--)
{
scanf("%d%d",&a.x,&a.y);
rootx=a.x;rooty=a.y;
if(ans[visx[rootx][rooty]][visy[a.x][a.y]]>0)//如果跟已经搜到过的点联通直接输出
{
printf("%d\n",ans[visx[rootx][rooty]][visy[a.x][a.y]]);
continue;
}
else{
t=BFS(a);
printf("%d\n",t);
}
ans[rootx][rooty]=t;//重点,自己的父点还是自己,不然出现重点会出错
}
}
dfs代码:
#include<bits/stdc++.h>
using namespace std;
struct node
{
int x,y;
};
int n,m;
char mm[1005][1005];
int dx[4]={1,-1,0,0};
int dy[4]={0,0,-1,1};
int visx[1005][1005];
int visy[1005][1005];
int ans[1005][1005];
int rootx,rooty;
int as=1;
queue<node >q;
bool judge(node a,node b)
{
if(a.x<1||a.x>n||a.y<1||a.y>n)return false;
if(b.x<1||b.x>n||b.y<1||b.y>n)return false;
if(mm[a.x][a.y]==mm[b.x][b.y])return false;
else return true;
}
void dfs(node a)
{
visx[a.x][a.y]=rootx;
visy[a.x][a.y]=rooty;
node t;
for(int i=0;i<4;i++)
{
t.x=a.x+dx[i];
t.y=a.y+dy[i];
if(judge(a,t)&&visx[t.x][t.y]==0)
{
visx[t.x][t.y]=rootx;
visy[t.x][t.y]=rooty;
as++;
dfs(t);
}
}
}
int main()
{
memset(ans,0,sizeof(ans));
//memset(visx,0,sizeof(visx));
scanf("%d%d",&n,&m);
char ch=getchar();
for(int i=1;i<=n;i++)
{
scanf("%s",mm[i]+1);
}
int x,y;
node a;
int t;
while(m--)
{
scanf("%d%d",&a.x,&a.y);
rootx=a.x;rooty=a.y;
if(ans[visx[rootx][rooty]][visy[a.x][a.y]]>0)
{
printf("%d\n",ans[visx[rootx][rooty]][visy[a.x][a.y]]);
continue;
}
else{
dfs(a);
printf("%d\n",as);
}
ans[rootx][rooty]=as;
as=1;
}
}