zoukankan      html  css  js  c++  java
  • HDU 5755 Gambler Bo

    Gambler Bo

    Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
    Total Submission(s): 676    Accepted Submission(s): 274
    Special Judge


    Problem Description
    Gambler Bo is very proficient in a matrix game.

    You have a N×M matrix, every cell has a value in {0,1,2}.

    In this game, you can choose a cell in the matrix, plus 2 to this cell, and plus 1 to all the adjacent cells.

    for example, you choose the cell (x,y), the value of (x,y) will be plused 2, and the value of (x1,y)(x+1,y)(x,y1)(x,y+1) will be plused 1.

    if you choose the cell (1,2), the cell (1,2) will be plused 2, and the cell (2,2)(1,1)(1,3) will be plused 1, the cell (0,2) won't be changed because it's out of the matrix.

    If the values of some cells is exceed 2, then these values will be modulo 3.

    Gambler Bo gives you such a matrix, your task is making all value of this matrix to 0 by doing above operations no more than 2NM times.
     
    Input
    First line, an integer T. There are T test cases.

    In each test, first line is two integers N,M, and following N lines describe the matrix of this test case.

    T10,1N,M30, the matrix is random and guarantee that there is at least one operation solution.
     
    Output
    For each test, first line contains an integer num(0num2NM) describing the operation times.

    Following num lines, each line contains two integers x,y(1xN,1yM) describing the operation cell.

    The answer may not be unique, you can output any one.

    Sample Input
    2
    2 3
    2 1 2
    0 2 0
    3 3
    1 0 1
    0 1 0
    1 0 1
    Sample Output
    1
    1 2
    5
    1 1
    1 3
    2 2
    3 1
    3 3

    用高斯消元法可解。每个位置的结果可以由他本身和四个方向上的变化决定。

    那么设横坐标为每个位置上的数值(一共n*m个位置),纵坐标为对这个数值的影响。A[i][j]=1表示j使i+1 ,A[i][j]=2表示j使i+2  同理A[i][j]=0表示j使i+0

    那么就可以构造一个(n*m) *(n*m)的方阵。设X为(n*m)*1的矩阵表示n*m个位置每个位置增加的次数, B为(n*m)*1的矩阵,B与题目中给的值有关,这里表示增加多少使得终态为0.

    AX=B,解出X矩阵就行了..

    卧槽 好烦 写的这么乱,不过还是挺好理解的....

    /* ***********************************************
    Author        :guanjun
    Created Time  :2016/7/28 8:36:24
    File Name     :hdu5755.cpp
    ************************************************ */
    #include <iostream>
    #include <cstring>
    #include <cstdlib>
    #include <stdio.h>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <set>
    #include <map>
    #include <string>
    #include <math.h>
    #include <stdlib.h>
    #include <iomanip>
    #include <list>
    #include <deque>
    #include <stack>
    #define ull unsigned long long
    #define ll long long
    #define mod 3
    #define INF 0x3f3f3f3f
    #define maxn 10010
    #define cle(a) memset(a,0,sizeof(a))
    const ull inf = 1LL << 61;
    const double eps=1e-5;
    using namespace std;
    
    int a[1100][1100];
    int A[1100][1100];
    int x[1100];
    int dir[4][2]={1,0,0,1,0,-1,-1,0};
    int exgcd(int a,int b,int &x,int &y){
        if(!b){x = 1; y = 0; return a;}
        else{
            int r = exgcd(b,a%b,y,x);
            y -= x * (a/b);
            return r;
        }
    }
    int lcm(int a,int b){
        int x = 0, y =0;
        return a / exgcd(a,b,x,y) * b;
    }
    void Gauss(int n,int m){
        int r,c;
        //列主元消去
        for(r=0,c=0;r<n&&c<m;c++){
            int maxr=r;
            for(int i=r+1;i<n;i++)if(abs(A[i][c])>abs(A[maxr][c]))maxr=i;
            if(maxr!=r)for(int i=c;i<=m;i++)swap(A[r][i],A[maxr][i]);
            if(!A[r][c])continue;
            for(int i=r+1;i<n;i++)if(A[i][c]){
                int d=lcm(A[i][c],A[r][c]);
                int t1=d/A[i][c],t2=d/A[r][c];
                for(int j=c;j<=m;j++)
                    A[i][j]=((A[i][j]*t1-A[r][j]*t2)%mod+mod)%mod;
            }
            r++;
        }
        for(int i=r;i<n;i++)if(A[i][m])return ;
        //从下到上
        for(int i=r-1;i>=0;i--){
            x[i]=A[i][m];
            for(int j=i+1;j<m;j++)
                x[i]=((x[i]-A[i][j]*x[j])%mod+mod)%mod;
            int x1=0,y1=0;
            //这里是用exgcd求逆元,也可以用费马小定理求,如果mod是素数
            int d = exgcd(A[i][i],mod,x1,y1);
            //cout<<"d "<<d<<endl;
            x1=((x1%mod)+mod)%mod;
            x[i]=x[i]*x1%mod;
        }
    }
    int main()
    {
        #ifndef ONLINE_JUDGE
        freopen("in.txt","r",stdin);
        #endif
        //freopen("out.txt","w",stdout);
        int t,n,m;
        cin>>t;
        while(t--){
            scanf("%d%d",&n,&m);
            for(int i=0;i<n;i++){
                for(int j=0;j<m;j++)scanf("%d",&a[i][j]);
            }
            cle(A);
            for(int i=0;i<n*m;i++){
                A[i][i]=2;//选择自己 加2
                int r=i/m;int c=i%m;
    
                for(int j=0;j<4;j++){
                    int x=r+dir[j][0];
                    int y=c+dir[j][1];
                    if(x<n&&x>=0&&y<m&&y>=0)A[i][x*m+y]=1;//四个方向+1
                }
                A[i][n*m]=(3-a[r][c])%3;//每个位置需要加的数  和初始状态有关
            }
            Gauss(n*m,n*m);
            int cnt=0;
            vector<int>v;
            for(int i=0;i<n*m;i++){
                while(x[i]){
                    x[i]--;
                    v.push_back(i);
                }
            }
            printf("%d
    ",v.size());
            for(int i=0;i<v.size();i++){
                int r=v[i]/m;
                int c=v[i]%m;
                r++,c++;
                printf("%d %d
    ",r,c);
            }
        }
        return 0;
    }
  • 相关阅读:
    yarn的学习之1-架构
    HDFS的存储策略
    搭建简单的hadoop集群(译文)
    构建高可靠hadoop集群之5-服务级别授权
    构建高可靠hadoop集群之4-保全模式
    构建高可靠hadoop集群之4-权限指引
    构建高可靠hadoop集群之3- Quorum Journal Manager
    构建高可靠hadoop集群之0-hadoop用户向导
    构建高可靠hadoop集群之2-机栈
    构建高可靠hadoop集群之1-理解hdfs架构
  • 原文地址:https://www.cnblogs.com/pk28/p/5713509.html
Copyright © 2011-2022 走看看