zoukankan      html  css  js  c++  java
  • P3164 [CQOI2014]和谐矩阵(高斯消元 + bitset)

    题意:构造一个$n*m$矩阵 使得每个元素和上下左右的xor值=0

    题解:设第一行的每个元素值为未知数 可以依次得到每一行的值

       然后把最后一行由题意条件 得到$m$个方程 高斯消元解一下 bitset写起来比较方便

    #include <stdio.h>
    #include <iostream>
    #include <algorithm>
    #include <bitset>
    using namespace std;
    const int MAXN = 45;
    
    int n, m;
    bitset<MAXN> a[MAXN][MAXN];
    bitset<MAXN> b[MAXN];
    int ans[MAXN];
    
    int dx[] = {-1, -1, -1, -2};
    int dy[] = {-1, 0, 1, 0};
    
    bool check(int x, int y) {
        if(x >= 1 && x <= n && y >= 1 && y <= m) return true;
        return false;
    }
    
    void gauss() {
        for(int i = 1, now = 1; i <= m && now <= m; now++) {
            for(int j = i; j <= m; j++) {
                if(b[j][now]) {
                    std::swap(b[j], b[i]);
                    break;
                }
            }
            if(!b[i][now]) ans[now] = 1;
            for(int j = i + 1; j <= m; j++) {
                if(b[j][now]) {
                    b[j] ^= b[i];
                }
            }
            i++;
        }
    
        for(int i = m; i >= 1; i--) {
            for(int j = i + 1; j <= m; j++) {
                if(b[i][j]) {
                    ans[i] ^= ans[j];
                }
            }
        }
    }
    
    int main() {
        scanf("%d%d", &n, &m);
        
        for(int i = 1; i <= m; i++) a[1][i][i] = 1;
        for(int i = 2; i <= n; i++) 
            for(int j = 1; j <= m; j++) {
                for(int k = 0; k < 4; k++) {
                    int nx = i + dx[k];
                    int ny = j + dy[k];
                    if(check(nx, ny)) {
                        a[i][j] ^= a[nx][ny];
                    }
                }
            }
    
        for(int i = 1; i <= m; i++) {
            b[i] = a[n][i];
            if(n - 1 >= 1) b[i] ^= a[n - 1][i];
            if(i - 1 >= 1) b[i] ^= a[n][i - 1];
            if(i + 1 <= m) b[i] ^= a[n][i + 1];
        }
        gauss();
    
        for(int i = 1; i <= n; i++) {
            for(int j = 1; j <= m; j++) {
                int res = 0;
                for(int t = 1; t <= m; t++) {
                    if(a[i][j][t]) res ^= ans[t];
                }
                if(j != m) printf("%d ", res);
                else printf("%d
    ", res);
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    ObjectForScripting 注册
    取消mysql表中timestamp字段的自动更新
    分片与非分片使用聚合的区别
    java类加载过程
    springboot中使用solr8
    第四章
    获取cookie的两种方式和session共享解决方案
    剑指 Offer 57. 和为s的两个数字
    第三章
    第五章
  • 原文地址:https://www.cnblogs.com/lwqq3/p/12731828.html
Copyright © 2011-2022 走看看