zoukankan      html  css  js  c++  java
  • hdu 5755 Gambler Bo 高斯消元

    题目链接

    给n*m的方格, 每个格子有值{0, 1, 2}。 然后可以对格子进行操作, 如果选择了一个格子, 那么这个格子的值+2, 这个格子上下左右的格子+1, 并且模3。

    问你将所有格子变成0的操作方法。

    其实就是一个模3的方程组, 高斯消元就可以了。 不知道为什么昨天比赛就是想不到......

    #include <iostream>
    #include <vector>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <complex>
    #include <cmath>
    #include <map>
    #include <set>
    #include <string>
    #include <queue>
    #include <stack>
    #include <bitset>
    using namespace std;
    #define pb(x) push_back(x)
    #define ll long long
    #define mk(x, y) make_pair(x, y)
    #define lson l, m, rt<<1
    #define mem(a) memset(a, 0, sizeof(a))
    #define rson m+1, r, rt<<1|1
    #define mem1(a) memset(a, -1, sizeof(a))
    #define mem2(a) memset(a, 0x3f, sizeof(a))
    #define rep(i, n, a) for(int i = a; i<n; i++)
    #define fi first
    #define se second
    typedef complex <double> cmx;
    typedef pair<int, int> pll;
    const double PI = acos(-1.0);
    const double eps = 1e-8;
    const int mod = 3;
    const int inf = 1061109567;
    const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
    int a[901][902];
    int n, b[902], x[902], m;
    int gcd(int a, int b)
    {
        return b?gcd(b, a%b):a;
    }
    int lcm(int a, int b)
    {
        return a/gcd(a, b)*b;
    }
    ll inv(ll a, ll m)
    {
        if(a == 1)
            return 1;
        return inv(m%a, m)*(m-m/a)%m;
    }
    int gauss(int equ, int var)
    {
        int max_r, col, k;
        for(k = 0, col = 0; k < equ && col < var; k++, col++) {
            max_r = k;
            for(int i = k + 1; i < equ; i ++) {
                if(abs(a[i][col]) > abs(a[max_r][col]))
                    max_r = i;
            }
            if(a[max_r][col] == 0) {
                k--;
                continue;
            }
            if(max_r != k) {
                for(int j = col; j < var+1; j++) {
                    swap(a[k][j], a[max_r][j]);
                }
            }
            for(int i = k + 1; i < equ; i++) {
                if(a[i][col]) {
                    int LCM = lcm(abs(a[i][col]), abs(a[k][col]));
                    int ta = LCM/abs(a[i][col]);
                    int tb = LCM/abs(a[k][col]);
                    if(a[i][col] * a[k][col] < 0)
                        tb = -tb;
                    for(int j = col; j < var+1; j++) {
                        a[i][j] = ((a[i][j]*ta - a[k][j]*tb)%mod+mod)%mod;
                    }
                }
            }
            for(int i = var-1; i >= 0; i--) {
                int tmp = a[i][var];
                for(int j = i+1; j < var; j++) {
                    if(a[i][j]) {
                        tmp -= a[i][j]*x[j];
                        tmp = (tmp%mod+mod)%mod;
                    }
                }
                x[i] = a[i][i]*tmp%mod;
            }
        }
    }
    int check(int x)
    {
        return x >=0 && x < n*m;
    }
    int main()
    {
        int t;
        cin>>t;
        while(t--) {
            scanf("%d%d", &n, &m);
            for(int i = 0; i < n*m; i++) {
                scanf("%d", &b[i]);
            }
            mem(x);
            mem(a);
            for(int i = 0; i < n*m; i++) {
                int u = i-m, d = i+m;
                int l = i-1, r = i+1;
                if(check(u)) {
                    a[i][u] = 1;
                }
                if(check(d)) {
                    a[i][d] = 1;
                }
                if(check(l)&&i%m!=0) {
                    a[i][l] = 1;
                }
                if(check(r)&&(i+1)%m!=0) {
                    a[i][r] = 1;
                }
                a[i][i] = 2;
                a[i][n*m] = (3-b[i])%3;
            }
            n *= m;
            gauss(n, n);
            int cnt = 0;
            for(int i = 0; i < n; i++) {
                if(x[i])
                    cnt += x[i];
            }
            printf("%d
    ", cnt);
            for(int i = 0; i < n; i++) {
                while(x[i]) {
                    printf("%d %d
    ", i/m+1, i%m+1);
                    x[i]--;
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    Net
    GUI
    第三方模块
    步入大四的第一天 2020/9/3
    期末复习计划及每日更新 8/10-9/2
    成都,come back 2020/8/10
    回家第三天 2020/7/31
    连续两天的好太阳的一天 2020/7/27
    规划规划,接下来的一个月该如何安排 7/25
    紧紧张张又兴兴奋奋的一天 2020/7/24
  • 原文地址:https://www.cnblogs.com/yohaha/p/5710264.html
Copyright © 2011-2022 走看看