洛谷P1141 01迷宮

題目描述

有一個僅由數字0與1組成的n×n格迷宮。若你位於一格0上,那麼你可以移動到相鄰4格中的某一格1上,同樣若你位於一格1上,那麼你可以移動到相鄰4格中的某一格0上。

你的任務是:對於給定的迷宮,詢問從某一格開始能移動到多少個格子(包含自身)。

輸入輸出格式
輸入格式:

輸入的第1行爲兩個正整數n,m。

下面n行,每行n個字符,字符只可能是0或者1,字符之間沒有空格。

接下來m行,每行2個用空格分隔的正整數i,j,對應了迷宮中第i行第j列的一個格子,詢問從這一格開始能移動到多少格。

輸出格式:

輸出包括m行,對於每個詢問輸出相應答案。

輸入輸出樣例

輸入樣例#1:
2 2
01
10
1 1
2 2

輸出樣例#1:
4
4

說明

所有格子互相可達。

對於20%的數據,n≤10;

對於40%的數據,n≤50;

對於50%的數據,m≤5;

對於60%的數據,n≤100,m≤100;

對於100%的數據,n≤1000,m≤100000。

果然是比較入門的BFS,適合退役大半年的我復出。。。

加個優化:因爲同一路線任意一點延展路徑固定,所以我們保存以前路線,下次掃描時判斷。
另一種思路:可以用連通塊維護並查集,輸出該方格所在的聯通快的點(然而我都忘了怎麼寫並查集···)
代碼如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int N=1005,dx[4]={-1,0,1,0},dy[4]={0,1,0,-1};
struct node
{
    int x,y;
}x;
bool a[N][N];
int vis[N][N],n,m,n1=0,rec[N*N];
int bfs(node b)
{
    int s=0,i,fx,fy;
    node t,r;
    queue<node>q;
    q.push(b);
    vis[b.x][b.y]=n1;
    while(!q.empty())
    {
        r=q.front();
        q.pop();
        s++;
        for(i=0;i<4;i++)
        {
            fx=r.x+dx[i];
            fy=r.y+dy[i];
            if(fx>=1&&fx<=n&&fy>=1&&fy<=n&&a[r.x][r.y]!=a[fx][fy]&&!vis[fx][fy])
            {
                t.x=fx;
                t.y=fy;
                vis[t.x][t.y]=n1;
                q.push(t);
            }
        }
    }
    return s;
}
int main()
{
    int i,j;
    char c;
    ios::sync_with_stdio(false);
    cin>>n>>m;
    for(i=1;i<=n;i++)
        for(j=1;j<=n;j++)
        {
            cin>>c;
            a[i][j]=c-'0';
        }
    for(i=1;i<=m;i++)
    {
        cin>>x.x>>x.y;
        if(vis[x.x][x.y])
            cout<<rec[vis[x.x][x.y]]<<endl;
        else
        {
            n1++;
            rec[n1]=bfs(x);
            cout<<rec[n1]<<endl;
        }
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章