1. 程式人生 > >P1141 01迷宮題解

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。


#include<iostream>
#include<cstdio>
using namespace std;
int fx[5]={0,0,1,0,-1},fy[5]={0,1,0,-1,0},n,m,a[1001][1001],ans[1001][1001],mgx[1000001],mgy[1000001],x,y;  //陣列啥的開大點,防爆(炸)嘛。
bool b[1001][1001];
void bfs(int x,int y)
{
    int h=0,t=1,tx,ty;b[x][y]=1,mgx[h]=x,mgy[h]=y;  //頭標尾標啥的賦初值。mgx[h]可改成mgx[0]都一樣。(說明一下,mgx和mgy是廣搜用的佇列。)
    while(h<t)  //do-while和while應該都可以。
    {
        for(int i=1;i<=4;i++)  //四向搜尋。
        {
            tx=mgx[h]+fx[i],ty=mgy[h]+fy[i];  //tx/ty,用來判斷下一步。
            if((tx>=1&&tx<=n)&&(ty>=1&&ty<=n)&&(a[tx][ty]!=a[mgx[h]][mgy[h]])&&(!b[tx][ty]))mgx[t]=tx,mgy[t]=ty,b[tx][ty]=1,t++;  //沒有超界並且達到此點不等於下點的值並且沒走過此點則存入佇列。
        }
        h++;
    }
    for(int i=0;i<t;i++)ans[mgx[i]][mgy[i]]=t;
}
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)scanf("%1d",&a[i][j]);  //讀入,也可用字元讀入。
    for(int i=1;i<=m;i++)
    {
        cin>>x>>y;  //讀入起始點。
        if(!b[x][y])bfs(x,y);
        cout<<ans[x][y]<<endl;  //輸出答案。
    }
}