https://www.luogu.org/problem/P1141
題目描述
有一個僅由數字0與1組成的n×n格迷宮。若你位於一格0上,那麼你可以移動到相鄰44格中的某一格1上,同樣若你位於一格1上,那麼你可以移動到相鄰4格中的某一格0上。
你的任務是:對於給定的迷宮,詢問從某一格開始能移動到多少個格子(包含自身)。
輸入格式
第11行爲兩個正整數n,m。
下面n行,每行n個字符,字符只可能是0或者1,字符之間沒有空格。
接下來m行,每行22個用空格分隔的正整數i,j,對應了迷宮中第i行第j列的一個格子,詢問從這一格開始能移動到多少格。
輸出格式
m行,對於每個詢問輸出相應答案。
思路:本來寫的代碼只是判斷之前搜過了之後就不用搜了,這樣還會出現重複的情況,3組樣例超時了,關鍵就在vis上面,每次不用清零,直接判斷有沒有訪問過,訪問過就不用在訪問了。
只要是連通的答案就一定一樣。
#include <stdio.h>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <queue>
#include<map>
#include<set>
using namespace std;
const int inf = 0x3f3f3f3f;
typedef long long ll;
const int MAXN=30000010;
int n,m;
struct node
{
int x;
int y;
int time;
} start, now;
int num=0;
char mapp[1010][1010];
int vis[1010][1010]={0};
int ans[1010*1010]={0};
int dir[4][2]={0,1,0,-1,1,0,-1,0};
ll bfs(int x,int y){
ll sum=1;
queue<node> q;
num++;
start.x=x;
start.y=y;
start.time=0;
q.push(start);
vis[x][y]=num;//###
while(!q.empty()){
now=q.front();
q.pop();
int flag=0;
for(int i=0;i<4;i++){
start.x=now.x+dir[i][0];
start.y=now.y+dir[i][1];
start.time=now.time+1;
if(start.x>=1&&start.y>=1&&start.x<=n&&start.y<=n&&vis[start.x][start.y]==0){
if(mapp[now.x][now.y]=='0'&&mapp[start.x][start.y]=='1'||mapp[now.x][now.y]=='1'&&mapp[start.x][start.y]=='0'){
vis[start.x][start.y]=num;//###
q.push(start);
sum++;
}
}
}
}
ans[num]=sum;//###
return sum;
}
int main()
{
ios::sync_with_stdio(false);
int x,y;
cin>>n>>m;
string s;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cin>>mapp[i][j];
}
}
while(m--){
cin>>x>>y;
if(vis[x][y]!=0)
cout<<ans[vis[x][y]]<<endl;//###
else{
ll sum=bfs(x,y);
cout<<sum<<endl;
}
}
return 0;
}