luoguP1162填涂颜色

题目链接

这道题刚开始打的暴力,64分。

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

const int N = 30;
int n, a[N][N], last[N];

int main () { 
    cin >> n;
    for(int i = 0 ; i < n ; i ++) 
        for(int j = 0 ; j < n ; j ++)
            scanf("%d", &a[i][j]);
    
    for(int i = 0 ; i < n ; i ++) {
        for(int j = n - 1; j >= 0 ; j --) {
            if(a[i][j] == 1) {
                last[i] = j;
                break;
            }
        }
    }
    for(int i = 0; i < n ; i ++) {
        bool flag = 0;
        for(int j = 0 ; j <= last[i] ; j ++) {
            if(a[i][j] == 1) flag = 1;
            if(a[i][j] == 0 && flag == 1) a[i][j] = 2;
        }
    }

    for(int i = 0 ; i < n ; i ++) {
        for(int j = 0 ; j < n ; j ++) {
            printf("%d ", a[i][j]);
        }
        printf("\n");
    }
    return 0;
}

不知道哪里出了错,开始想正解

没想出来然后看了题解没看懂(果然oier不适合看别人的代码)

但是大体思路了解了

广度优先搜索bfs

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

const int N = 30;
int n, a[N][N], last[N];

int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};

void bfs(int x, int y) {
    if(x < 0 || x >= n || y < 0 || y >= n || a[x][y] == 1) return;
    a[x][y] = 3;
    for(int i = 0; i < 4; i ++) {
        bfs(x + dx[i], y + dy[i]);
    }
}
void print() {
    for(int i = 0; i < n ; i ++) {
        for(int j = 0 ; j < n ; j ++) {
            if(a[i][j] == 3) printf("0 ");
            else if(a[i][j] == 0) printf("2 ");
            else printf("%d ", a[i][j]);
        }
        printf("\n");
    }
}
void read() {
    scanf("%d", &n);
    for(int i = 0 ; i < n ; i ++) 
        for(int j = 0; j < n ; j ++) 
            scanf("%d", &a[i][j]);
}
int main() {
    read();
    bfs(0, 0);
    print();
    return 0;
}

然鹅把这份代码交上去,32分,还没有刚开始打的暴力高。

下载了样例发现如果一堆1和边界把整个矩形分成几部分,我们只能解决左上角的那部分,举个简单例子:
0 0 0 1 1 1 0 0

0 0 0 1 0 1 0 0

0 0 0 1 0 1 0 0

1 1 1 1 0 1 0 0

1 0 0 0 0 1 0 0

1 0 0 0 0 1 0 0

1 0 0 0 0 1 0 0

1 1 1 1 1 1 0 0

但是题解的代码没有问题。

(陷入思考)

发现边界问题很重要

把所有输入输出都调成1 = 1; i <= n

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

const int N = 30;
int n, a[N][N], last[N];

int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};
bool book[N][N];

void bfs(int x, int y) {
    if(x < 0 || x > n || y < 0 || y > n || a[x][y] != 0||book[x][y] == 1) return;
    book[x][y] = 1;
    a[x][y] = 3;
    for(int i = 0; i < 4; i ++) {
        bfs(x + dx[i], y + dy[i]);
    }
}
void print() {
    // printf("********************\n");
    for(int i = 1; i <= n ; i ++) {
        for(int j = 1 ; j <= n ; j ++) {
            if(a[i][j] == 3) printf("0 ");
            else if(a[i][j] == 0) printf("2 ");
            else printf("%d ", a[i][j]);
        }
        printf("\n");
    }
}
void read() {
    scanf("%d", &n);
    for(int i = 1 ; i <= n ; i ++) 
        for(int j = 1; j <= n ; j ++) 
            scanf("%d", &a[i][j]);
}
int main() {
    read();
    bfs(0, 0);
    print();
    return 0;
}

发现一个破绽,即使输入输出的时候用了1到n,在矩阵的上下左右都留出了一列0,但是在搜索的时候只用到了左边和上面边界为0来绕过这堵墙,右面和下边还是没有用到。


最终!

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

const int N = 32;
int n, a[N][N], last[N];

int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};
bool book[N][N];

void bfs(int x, int y) {
    if(x < 0 || x > n + 1|| y < 0 || y > n + 1|| a[x][y] != 0||book[x][y] == 1) return;
    book[x][y] = 1;
    a[x][y] = 3;
    for(int i = 0; i < 4; i ++) {
        bfs(x + dx[i], y + dy[i]);
    }
}
void print() {
    // printf("********************\n");
    for(int i = 1; i <= n ; i ++) {
        for(int j = 1 ; j <= n ; j ++) {
            if(a[i][j] == 3) printf("0 ");
            else if(a[i][j] == 0) printf("2 ");
            else printf("%d ", a[i][j]);
        }
        printf("\n");
    }
}
void read() {
    scanf("%d", &n);
    for(int i = 1 ; i <= n ; i ++) 
        for(int j = 1; j <= n ; j ++) 
            scanf("%d", &a[i][j]);
}
int main() {
    read();
    bfs(0, 0);
    print();
    return 0;
}

这段代码和上一段唯一的区别就是把dfs里面的“判断边界”x > n || y > n
改成了x > n + 1 || y > n + 1使搜索的时候在右面和下面也可以绕过这堵墙。

最终AC了。

真是一波三折搞人心态。

posted @ 2020-10-12 20:50  Lvlb2333  阅读(51)  评论(0编辑  收藏  举报