1. 程式人生 > >洛谷P1141 01迷宮

洛谷P1141 01迷宮

block 答案 namespace string 存在 ostream ring 他能 ++

非常難受了可以說..一道普及/提高-的水題
我居然改了3天 提交了20次!!
我太弱了!!


正文開始:


題目描述:

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

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

輸入輸出格式


輸入格式:

第 1 行為兩個正整數 n,m 。

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

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


輸出格式:

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

分析題目:
這道題一眼就能看出來是個搜索題(DP?不存在的)。那麽一個顯然的做法就是:把圖存起來,對於每一個詢問都進行一次dfs。顯然這TLE了。(70分做法)

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<string>
#include<map>
#include<set>
#include<queue>
#define INF 0x3f3f3f3f
#define
inf 0x3f #define ll long long using namespace std; queue<int> q; int n,m,x,a[1001][1001],y,dx[]={-1,1,0,0},dy[]={0,0,-1,1},sum,vis[1001][1001],ans[1001]; char c; int dfs(int x,int y){ vis[x][y]=1; for(int i=0;i<4;i++){ int xx=x+dx[i]; int yy=y+dy[i]; if(a[x][y]==1){
if(xx>0&&yy>0&&xx<=n&&yy<=n&&a[xx][yy]==0&&vis[xx][yy]==0) { sum++; dfs(xx,yy); } } if(a[x][y]==0){ if(xx>0&&yy>0&&xx<=n&&yy<=n&&a[xx][yy]==1&&vis[xx][yy]==0) { sum++; dfs(xx,yy); } } } return sum; } int main(){ sum=1; cin>>n>>m; for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ vis[i][j]=0; cin>>c; if(c==0) a[i][j]=0; if(c==1) a[i][j]=1; } } for(int i=1;i<=m;i++){ cin>>x>>y; ans[i]=dfs(x,y); sum=1; for(int j=1;j<=n;j++){ for(int k=1;k<=n;k++){ vis[j][k]=0; } } } for(int i=1;i<=m;i++){ cout<<ans[i]<<endl; } return 0; }

那麽如何做到AC呢?
首先分析題目:

若你位於一格0上,那麽你可以移動到相鄰 4 格中的某一格 1 上,同樣若你位於一格1上,那麽你可以移動到相鄰 4 格中的某一格 0 上。

那麽我們可以做一個設想:對於每一個點,從這個點出發能到達的所有的點是一個值sum,那麽從他能到達的任意一點出發,也能有一個值sum,並且這兩個值相等。
但是!如果從這個點A出發到達不了的點B,那麽這個點B的答案和A不同。
我們可以把他理解成一個連通塊。
巨坑:數組要開1e6,不然坐等WA或者RE吧qwq.

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<string>
#include<map>
#include<set>
#include<queue>
#define INF 0x3f3f3f3f
#define inf 0x3f
#define ll long long
using namespace std;
queue<int> q;
int n,m,x,a[1001][1001],y,dx[]={-1,1,0,0},dy[]={0,0,-1,1},sum,vis[1001][1001],ans[1000001],num[1000001];
int k;
char c;
void dfs(int x,int y,int k){
    vis[x][y]=k;
    for(int i=0;i<4;i++){
        int xx=x+dx[i];
        int yy=y+dy[i];
        if(a[x][y]==1){
            if(xx>0&&yy>0&&xx<=n&&yy<=n&&a[xx][yy]==0&&vis[xx][yy]==0) {
                sum++;
                dfs(xx,yy,k);
            }
        }
        if(a[x][y]==0){
            if(xx>0&&yy>0&&xx<=n&&yy<=n&&a[xx][yy]==1&&vis[xx][yy]==0) {
                sum++;
                dfs(xx,yy,k);
            }
        }
    }
}
int main(){ 
    k=0;
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            vis[i][j]=0;
            cin>>c;
            if(c==0) a[i][j]=0;
            if(c==1) a[i][j]=1;
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            if(vis[i][j]==0){
                k++;
                sum=1;
                dfs(i,j,k);
                num[k]=sum;
            }
        }
    }
    for(int i=1;i<=m;i++){
        cin>>x>>y;
        int qwq=vis[x][y];
        ans[i]=num[qwq];
    }
    for(int i=1;i<=m;i++){
        cout<<ans[i]<<endl;
    }
    return 0;
}

洛谷P1141 01迷宮