[Luogu p1141] 01 maze

Portal

Face questions

Title Description

There is only a digital \ (0 \) and \ (1 \) consisting of \ (n \ times n \) grid maze. If you are located on a lattice 0, then you can move to an adjacent \ (4 \) cells in a cell \ (1 \) , the same if you are in a grid 1, then you can move to an adjacent \ (4 \) a lattice grid the \ (0 \) on.

Your task is: for a given maze inquiry can begin to move from one cell to the number of grid (including its own).

Input and output formats

Input Format

The first \ (1 \) behavior of two positive integers \ (n-, m \) .

Here \ (n-\) rows, each row \ (n-\) characters, characters can only be \ (0 \) or \ (1 \) with no spaces between characters.

Next, \ (\ m) rows, each row \ (2 \) , separated by a space positive integer \ (I, J \) , corresponding to the first maze \ (I \) row \ (J \) column a grid, able to move from start to ask how much this grid cell.

Output Format

\ (m \) line, the output for each query corresponding answers.

Sample input and output

Input # 1:

2 2
01
10
1 1
2 2

Output # 1:

4
4

Description / Tips

For the sample, all the grid up to each other.

For \ (20 \% \) data, \ (n-\ Le 10 \) ;

For \ (40 \% \) data, \ (n-\ Le 50 \) ;

For \ (50 \% \) data, \ (m \ Le. 5 \) ;

For \ (60 \% \) data, \ (n-\ Le 100, m \ Le 100 \) ;

For \ (100 \% \) data, \ (n-\ 1000 Le, m \ 100000 Le \) .

analysis

This question appears to be a very simple search, but look at this question of the scope of data, we can see that this question is actually bloodshed. And recent search of water Niwai, looking at this question, I suddenly idea came: Can a disjoint-set to do it?
It may, it is clear that we might block communication, then we can construct maps. One-dimensional two-dimensional map to believe we are already well placed to exploit directly (i,j)mapped to i*n+j, simple and crude.
And check on the details of the set I'm not saying too much, I just want to say, disjoint-set really is the most beautiful of the data structure in the world.
At that time I used an ordinary two-dimensional array dfsrun disjoint-set, but the result MLEof the 3points made 70pointsGood results.
As MLEwe can scroll across the map into an array, with disjoint-set, it is the simple things.
See in particular the code.

Code

Give dfsversions, note that this version I got 70points,Do not take a direct copyThen I have to pay attention to the spatial complexity, this is a lesson ah.

/*
 * @Author: crab-in-the-northeast 
 * @Date: 2020-02-19 23:01:54 
 * @Last Modified by: crab-in-the-northeast
 * @Last Modified time: 2020-02-19 23:41:37
 */

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

const int maxn = 1005;
const int maxn2 = 1000005;

int n;
int fa[maxn2],u[maxn2];
bool a[maxn][maxn];
int dx[4] = {1,-1,0,0};
int dy[4] = {0,0,1,-1}; 

int find(int x){//查
    return fa[x] == x?x:fa[x] = find(fa[x]);
}

void merge(int a,int b){//并
    int fa1 = find(a), fa2 = find(b);
    if(fa1 != fa2){
        u[fa1] += u[fa2];
        fa[fa2] = fa[fa1];
    }
}

// 以上都是并查集的板子,这里不再多说。

bool valid(int x,int y){
    return x>0&&x<=n&&y>0&&y<=n;
}//边界判断。

int dfs(int x,int y){
    int ind = x*n+y;//映射处理
    if(fa[ind] != -1) return find(ind);//记忆化
    fa[ind] = ind;
    u[ind] = 1;
    //初始化

    for(int i=0;i<4;i++){
        int nxtx = x+dx[i], nxty = y+dy[i];//枚举下一种情况的x坐标和y坐标。
        if(valid(nxtx,nxty) && a[x][y]!=a[nxtx][nxty])//合法。
            merge(ind,dfs(nxtx,nxty));//并。
    }
    
    return find(ind);//回溯
}

int main(){
    int T;
    scanf("%d%d",&n,&T);
    memset(fa,-1,sizeof(fa));
    for(int i = 1; i <= n ;i++)
        for(int j = 1; j <= n; j++)
            scanf("%1d",&a[i][j]);

    while(T--){
        int x,y;
        scanf("%d%d",&x,&y);
        printf("%d\n",u[dfs(x,y)]);
    }
    return 0;
}

Out of ACthe code (a rolling arrays)

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

const int maxn = 1005;
const int maxn2 = 1000005;

int n;
int fa[maxn2],u[maxn2];
char a[2][maxn];

int find(int x){
    return fa[x] == x?x:fa[x] = find(fa[x]);
}

void merge(int a,int b){
    int fa1 = find(a), fa2 = find(b);
    if(fa1 != fa2){
        u[fa1] += u[fa2];
        fa[fa2] = fa[fa1];
    }
}

int main(){
    int T;
    scanf("%d%d",&n,&T);
    memset(fa,-1,sizeof(fa));
    for(int i = 0; i < n; i++){
        scanf("%s",a[i&1]);//读入
        for(int j = 0; j < n; j++){
            int ind = i*n+j;//映射
            fa[ind] = ind;
            u[ind] = 1;
            if(i && a[(i-1)&1][j] !=a[i&1][j]) merge(ind-n,ind);//横向并
            if(j && a[i&1][j-1] != a[i&1][j]) merge(ind,ind-1);//纵向并
        }
    }

    while(T--){
        int x,y;
        scanf("%d%d",&x,&y);
        printf("%d\n",u[find(x*n-n+y-1)]);
        //这里蟹蟹懒。这里的原型应该是(x-1)*n+y-1,就是用了个乘法分配。
    }
    return 0;
}

Evaluation results

MLE 70: R30836609
AC 100 : R30837084

over.

Guess you like

Origin www.cnblogs.com/crab-in-the-northeast/p/luogu-p1141.html