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;
    }
  • 相关阅读:
    1094. Car Pooling
    121. Best Time to Buy and Sell Stock
    58. Length of Last Word
    510. Inorder Successor in BST II
    198. House Robber
    57. Insert Interval
    15. 3Sum java solutions
    79. Word Search java solutions
    80. Remove Duplicates from Sorted Array II java solutions
    34. Search for a Range java solutions
  • 原文地址:https://www.cnblogs.com/yohaha/p/5710264.html
Copyright © 2011-2022 走看看