zoukankan      html  css  js  c++  java
  • hdu 5755(Gauss 消元) &poj 2947

    Gambler Bo

    Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
    Total Submission(s): 1152    Accepted Submission(s): 471
    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
     
    Author
    绍兴一中
     
    Source
     
    Recommend
    wange2014

    gauss消元的mod 3 版本,把n*m个格子上的操作全部变成列向量,共n*m个,每个列向量有n*m个元素,做一遍gauss消元就能解出。

    另:优化后因为第i行的状态可以由i+1行确定,所以能建立m个方程,每个方程 M 个变量进行高斯消元,解出解后代回去得到每个元素应该被操作的次数。详见

    传送门

    我的裸gauss消元代码如下:

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<cmath>
      6 #define clr(x) memset(x,0,sizeof(x))
      7 #define clrdown(x) memset(x,-1,sizeof(x))
      8 #define maxn 910
      9 using namespace std;
     10 int A[maxn][maxn];
     11 int free_x[maxn];
     12 int x[maxn];
     13 int mov[4][2]={0,1,0,-1,1,0,-1,0};
     14 void init(int n,int m);
     15 void gauss(int n,int m);
     16 void print(int n,int m);
     17 int exgcd(int a,int b,int &x,int &y);
     18 int lcm(int a,int b);
     19 int gcd(int a,int b);
     20 int main()
     21 {
     22     int T,p,num,n,m;
     23     scanf("%d",&T);
     24     while(T--)
     25     {
     26         scanf("%d%d",&n,&m);
     27         init(n,m);
     28         gauss(n*m,n*m);
     29         print(n,m);
     30     }
     31     return 0;
     32 }
     33 void print(int n,int m)
     34 {
     35     int sum=0;
     36     for(int i=0;i<n*m;i++)
     37         sum+=x[i];
     38     printf("%d
    ",sum);
     39     for(int i=0;i<n;i++)
     40         for(int j=0;j<m;j++)
     41             while(x[i*m+j]>0)
     42             {
     43                 printf("%d %d
    ",i+1,j+1);
     44                 x[i*m+j]--;
     45             }
     46     return ;
     47 }
     48 void init(int n,int m)
     49 {
     50     int t;
     51     clr(A);
     52     for(int i=0;i<n;i++)
     53         for(int j=0;j<m;j++)
     54         {
     55             t=i*m+j;
     56             A[t][t]=2;
     57             for(int k=0;k<4;k++)
     58                 if(i+mov[k][0]>=0 && i+mov[k][0]<n && j+mov[k][1]>=0 && j+mov[k][1]<m)
     59                     A[(i+mov[k][0])*m+j+mov[k][1]][t]=1;
     60         }
     61     t=n*m;
     62     for(int i=0;i<n;i++)
     63         for(int j=0;j<m;j++)
     64         {
     65             scanf("%d",&A[i*m+j][t]);
     66             A[i*m+j][t]=(3-A[i*m+j][t])%3;
     67         }
     68     clrdown(x);
     69     clr(free_x);
     70 }
     71 void gauss(int n,int m)
     72 {
     73 //    for(int i=0;i<n;i++)
     74 //    {
     75 //       for(int j=0;j<=m;j++)
     76 //           printf("%d ",A[i][j]);
     77 //       printf("
    ");
     78 //    }
     79     int k,col,num=0,max_r,dou,max_x,LCM,ta,tb;
     80     for(k=0,col=0;k<n && col<m;k++,col++)
     81     {
     82         max_r=k;
     83         max_x=abs(A[k][col]);
     84         for(int i=k+1;i<n;i++)
     85             if(max_x<abs(A[i][col]))
     86             {
     87                 max_x=abs(A[i][col]);
     88                 max_r=i;
     89             }
     90         if(max_r!=k)
     91         {
     92             for(int j=col;j<=m;j++)
     93                 swap(A[k][j],A[max_r][j]);
     94         }
     95         if(A[k][col]==0)
     96         {
     97             k--;
     98             free_x[num++]=col;
     99             continue;
    100         }
    101         for(int i=k+1;i<n;i++)
    102         if(A[i][col])
    103         {
    104             LCM=lcm(A[k][col],A[i][col]);
    105             ta=LCM/A[i][col];
    106             tb=LCM/A[k][col];
    107             for(int j=col;j<=m;j++)
    108             {
    109                     A[i][j]=((A[i][j]*ta-A[k][j]*tb)%3+3)%3;
    110             }
    111         }
    112     }
    113     int temp;
    114     for(int i=0;i<num;i++)
    115         x[free_x[i]]=0;
    116     int  xi,yi;
    117     for(int i=k-1,c=m-1;i>=0;c=m-1,i--)
    118     {
    119         temp=A[i][m];
    120         while(x[c]!=-1)
    121         {
    122             if(A[i][c])
    123                 temp=((temp-(x[c]*A[i][c])%3)%3+3)%3;
    124             c--;
    125         }
    126         exgcd(A[i][c],3,xi,yi);
    127         xi=(xi%3+3)%3;
    128         x[c]=(temp*xi%3+3)%3;
    129     }
    130 //    for(int i=0;i<n;i++)
    131 //    {
    132 //        for(int j=0;j<=m;j++)
    133 //            printf("%d ",A[i][j]);
    134 //        printf("
    ");
    135 //    }
    136 //    for(int i=0;i<m;i++)
    137 //        printf("%d ",x[i]);
    138     return ;
    139 }
    140 int exgcd(int a,int b,int &x,int &y)
    141 {
    142     if(b==0)
    143     {
    144         x=1;
    145         y=0;
    146         return a;
    147     }
    148     else
    149     {
    150         int r=exgcd(b,a%b,y,x);
    151         y-=x*(a/b);
    152         return r;
    153     }
    154 }
    155 int gcd(int a,int b)
    156 {
    157     int c;
    158     while(b!=0)
    159     {
    160         c=a%b;
    161         a=b;
    162         b=c;
    163     }
    164     return a;
    165 }
    166 int lcm(int a,int b)
    167 {
    168     return a/gcd(a,b)*b;
    169 }

     同样的,poj2947: 【传送门

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<cmath>
      6 #define clr(x) memset(x,0,sizeof(x))
      7 #define clrdown(x) memset(x,-1,sizeof(x))
      8 #define maxn 310
      9 #define maxm 310
     10 #define mod 7
     11 using namespace std;
     12 int A[maxn][maxm];//Gauss消元的增广矩阵
     13 int x[maxm];//整数解集
     14 char week[7][10] = {"MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN"};
     15 char s1[10],s2[10];
     16 void init(int n,int m);//矩阵初始化操作
     17 int gauss(int n,int m);//gauss消元部分
     18 int exgcd(int a,int b,int &x,int &y);//扩展欧几里得求逆元,对于模mod的矩阵除法需要
     19 int lcm(int a,int b);
     20 int gcd(int a,int b);
     21 int findnum(char *s);
     22 int main()
     23 {
     24     int n,m,p;
     25     while(scanf("%d%d",&n,&m) && n && m)
     26     {
     27         init(n,m);
     28         p=gauss(m,n);
     29         if(p==-1)
     30             printf("Inconsistent data.
    ");
     31         if(p==-2)
     32             printf("Multiple solutions.
    ");
     33         if(p==0)
     34         {
     35             for(int i=0;i<n;i++)
     36                printf("%d%c", x[i], i == n-1 ?'
    ':' ');
     37         }
     38     }
     39     return 0;
     40 }
     41 //读入增广矩阵
     42 void init(int n,int m)
     43 {
     44     clr(A);
     45     int p,ct;
     46     for(int i=0;i<m;i++)
     47     {
     48         scanf("%d%s%s",&p,&s1,&s2);
     49         A[i][n]=((findnum(s2)-findnum(s1)+1)+mod)%mod;
     50         for(int j=0;j<p;j++)
     51         {
     52             scanf("%d",&ct);
     53             A[i][ct-1]++;
     54             A[i][ct-1]=A[i][ct-1]%mod;
     55         }
     56     }
     57     clrdown(x);
     58     return ;
     59 }
     60 int gauss(int n,int m)
     61 {
     62     int k,col,max_r,dou,max_x,LCM,ta,tb;
     63 //k为当前操作行,col为操作主元素所在列
     64     for(k=0,col=0;k<n && col<m;k++,col++)
     65     {
     66         //若A[K][col]不为col列最大,则将k行与k+1到n-1行中A[i][col]绝对值最大的行交换
     67         max_r=k;
     68         max_x=A[k][col];
     69         for(int i=k+1;i<n;i++)
     70             if(max_x<A[i][col])
     71             {
     72                 max_x=A[i][col];
     73                 max_r=i;
     74             }
     75         if(max_r!=k)
     76         {
     77             for(int j=col;j<=m;j++)
     78                 swap(A[k][j],A[max_r][j]);
     79         }
     80         //若k到n-1行A[i][col]全为0,则主元素指向当前行下一列的元素
     81         if(A[k][col]==0)
     82         {
     83             k--;
     84             //自由变元为当前col
     85             continue;
     86         }
     87         for(int i=k+1;i<n;i++)
     88         if(A[i][col])
     89         {
     90             LCM=lcm(A[k][col],A[i][col]);
     91             ta=LCM/A[i][col];
     92             tb=LCM/A[k][col];
     93             for(int j=col;j<=m;j++)
     94             {
     95                  A[i][j]=((A[i][j]*ta-A[k][j]*tb)%mod+mod)%mod;
     96             }
     97         }
     98     }
     99     for(int i=k;i<n;i++)
    100         if(A[i][m]!=0)
    101             return -1;
    102     if(m-k>0) return -2;
    103     int  xi,yi,temp;
    104     for(int i=k-1,c=m-1;i>=0;c=m-1,i--)
    105     {
    106         temp=A[i][m];
    107         while(x[c]!=-1)
    108         {
    109             if(A[i][c])
    110                 temp=((temp-x[c]*A[i][c])%mod+mod)%mod;
    111             c--;
    112         }
    113         temp=(temp%mod+mod)%mod;
    114         exgcd(A[i][c],mod,xi,yi);
    115         xi=(xi%mod+mod)%mod;
    116         x[c]=((temp*xi)%mod+mod)%mod;
    117         if(x[c]<3) x[c]+=mod;
    118     }
    119     return 0;
    120 }
    121 int exgcd(int a,int b,int &x,int &y)
    122 {
    123     if(b==0)
    124     {
    125         x=1;
    126         y=0;
    127         return a;
    128     }
    129     else
    130     {
    131         int r=exgcd(b,a%b,y,x);
    132         y-=x*(a/b);
    133         return r;
    134     }
    135 }
    136 int gcd(int a,int b)
    137 {
    138     int c;
    139     while(b!=0)
    140     {
    141         c=a%b;
    142         a=b;
    143         b=c;
    144     }
    145     return a;
    146 }
    147 int lcm(int a,int b)
    148 {
    149     return a/gcd(a,b)*b;
    150 }
    151 int findnum(char *s)
    152 {
    153     for(int i=0;i<mod;i++)
    154     {
    155         if(strcmp(s,week[i])==0)
    156             return i;
    157     }
    158 }
    Gauss消元
  • 相关阅读:
    解决spring配置文件没有提示的问题
    SpringMVC 中HttpMessageConverter简介和Http请求415 Unsupported Media Type的问题
    在编辑Spring的配置文件时的自动提示
    Java注释@interface的用法【转】
    spring-autowire机制
    一些汇编指令
    Windows底层开发前期学习准备工作
    log4j.properties中的这句话“log4j.logger.org.hibernate.SQL=DEBUG ”该怎么写在log4j.xml里面呢?
    log4j 配置文件 (XML/.properties)
    [VC]C++ operator 两种用法
  • 原文地址:https://www.cnblogs.com/wujiechao/p/5862935.html
Copyright © 2011-2022 走看看