hihor学习日记:hiho一下 第五十七周(高斯消元)

http://hihocoder.com/contest/hiho57/problem/1

高斯消元的变种,因为图很小所以而且每一个小格子都得为1,那么就把图中对某个小格子有作用的点标记起来,而他们的共同作用次数为奇数的话,小格子的状态变化,反之不变,
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
注意这里在处理矩阵时,对于第i列的数字如果原本就为0的话,就不用处理,否则会错误

AC代码:

#include <bits/stdc++.h>

using namespace std;
#define LL long long
const int Mod = 1e9 + 7;
const int maxn = 1e5 + 5;
const double eps = 0.00000001;
const int INF = 0x3f3f3f3f;

struct Change{
    int x, y;

    bool friend operator < (Change a, Change b){
        if(a.x == b.x) return a.y < b.y;
        return a.x < b.x;
    }
}ch[maxn];

int a[35][35];
int b[35], x[35];
bool manySolution = false, noSolution = false;

void Swap(int i, int j) {
    for (int k = 1; k <= 30; k ++)
        swap(a[i][k], a[j][k]);
    swap(b[i], b[j]);
}

bool Check(int i) {
    bool vis = false;
    for (int k = 1; k <= 30; k ++) {
        if(a[i][k]) vis = true;
    }
    if(!vis && b[i]) return false;
    return true;
}

void GS() {
    for (int i = 1; i <= 30; i ++) {
        bool vis = false;
        for (int j = i; j <= 30; j ++) {
            if(a[i][j] != 0) {
                Swap(i, j);
                vis = true;
                break;
            }
        }
        if(!vis) {
            manySolution = true;
            continue;
        }
        for (int j = i + 1; j <= 30; j ++) {
            if(a[j][i]) {//如果原本就为0,就不处理
                for (int k = i; k <= 30; k ++)
                    a[j][k] = a[j][k] ^ a[i][k];
                b[j] = b[j] ^ b[i];
            }
        }
    }
    for (int i = 1; i <= 30; i ++) {
        if(!Check(i)) {
            noSolution = true;
            return ;
        }
    }
    for (int i = 30; i >= 1; i --) {
        for (int j = i + 1; j <= 30; j ++) {
            b[i] = b[i] ^ (a[i][j] * x[j]);
            a[i][j] = 0;
        }
        x[i] = b[i] / a[i][i];
    }
}

int main()
{
    char c[35][35];
    for (int i = 1; i <= 5; i ++)
        scanf("%s", c[i]);
    for (int i = 1; i <= 5; i ++)
        for (int j = 1; j <= 6; j ++) {
            b[(i - 1) * 6 + j] = c[i][j - 1] - '0';
            b[(i - 1) * 6 + j] ^= 1;
        }
    memset(a, 0, sizeof(a));
    for (int i = 1; i <= 30; i ++) {
        a[i][i] = 1;
        if(i + 1 <= 30 && i + 1 >= 1 && i % 6 != 0) a[i][i + 1] = 1;
        if(i - 1 <= 30 && i - 1 >= 1 && i % 6 != 1) a[i][i - 1] = 1;
        if(i + 6 <= 30 && i + 6 >= 1) a[i][i + 6] = 1;
        if(i - 6 <= 30 && i - 6 >= 1) a[i][i - 6] = 1;
    }
    GS();
    int cnt = 0;
    for (int i = 1; i <= 30; i ++) {
        if(x[i]) {
            if(i % 6) {
                ch[cnt ++] = Change{i/6 + 1, i % 6};
            }else {
                ch[cnt ++] = Change{i/6, 6};
            }
        }
    }
    sort(ch, ch +cnt);
    cout << cnt << endl;
    for (int i = 0; i < cnt; i ++)
        cout << ch[i].x << " " << ch[i].y << endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/henu_jizhideqingwa/article/details/85224442
今日推荐