1 条题解

  • 0
    @ 2025-8-24 21:24:34

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar Cet6_427
    **

    搬运于2025-08-24 21:24:33,当前版本为作者最后更新于2017-09-28 08:04:34,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    一、 40分做法

    很容易想到枚举矩阵中的每一个数判断其变还是不变,最后判断整个矩阵是否满足条件。但是会TLE,只能过掉40%的数据...

    二、100分做法

    N的范围只有18,所以第一行只有不超过2^18种可能性,是我们可以枚举的,接下来我们可以根据第一行计算出第二行,再根据第二行又能计算出第三行以此类推……

    最后的时间复杂度为O(2^n * n ^ 2)可以承受...

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <iostream>
    #include <vector>
    #include <cmath>
    #include <iterator>
    #define LL long long
    #define mem(a, b) memset(a, b, sizeof(a))
    #define rep(i, a, b) for(int i = (a); i <= (b); i++)
    using namespace std;
    const int maxn = 20;
    const int INF = 10000000000;
    int N, A[maxn][maxn], B[maxn][maxn];
    int query(int cur){
        mem(B, 0);
        rep(j, 0, N-1){
            if(cur & (1<<j)) B[0][j] = 1;
            else if(A[0][j] == 1) return INF;
        }
        rep(i, 1, N-1) rep(j, 0, N-1){
            int sum = 0;
            if(i > 1) sum += B[i-2][j];
            if(j > 0) sum += B[i-1][j-1];
            if(j < N-1) sum += B[i-1][j+1];
            B[i][j] = sum % 2;
            if(A[i][j] == 1 && B[i][j] == 0) return INF;
        }
        int cnt = 0;
        rep(i, 0, N-1) rep(j, 0, N-1)
            if(A[i][j] != B[i][j]) cnt++;
        return cnt;
    }
    int main(){
        scanf("%d", &N);
        rep(i, 0, N-1) rep(j, 0, N-1) scanf("%d", &A[i][j]);
        int ans = INF;
        rep(i, 0, (1<<N)-1) ans = min(ans, query(i));
        if(ans == INF) ans = -1;
        printf("%d\n", ans);
        return 0;
    }
    
    
    • 1

    信息

    ID
    388
    时间
    1000ms
    内存
    125MiB
    难度
    5
    标签
    递交数
    0
    已通过
    0
    上传者