Gauss 消元(模板)

  1 /* 
  2     title:Gauss消元整数解/小数解整数矩阵模板 
  3     author:lhk
  4     time: 2016.9.11
  5     没学vim的菜鸡自己手打了     
  6 */
  7 #include<cstdio>
  8 #include<iostream>
  9 #include<cstring>
 10 #include<algorithm>
 11 #include<cmath>
 12 #define clr(x) memset(x,0,sizeof(x))
 13 #define clrdown(x) memset(x,-1,sizeof(x))
 14 #define maxn 910
 15 #define maxm 910 
 16 #define mod 3 
 17 using namespace std;
 18 int A[maxn][maxm];//Gauss消元的增广矩阵 
 19 int free_x[maxm];//自由变元的位置 
 20 int x[maxm];//整数解集 
 21 double xd[maxm];//小数解集 
 22 void init(int n,int m);//矩阵初始化操作 
 23 int gauss(int n,int m);//gauss消元部分 
 24 void print(int n);//输出解集 
 25 int exgcd(int a,int b,int &x,int &y);//扩展欧几里得求逆元,对于模mod的矩阵除法需要 
 26 int lcm(int a,int b);
 27 int gcd(int a,int b);
 28 int main()
 29 {
 30     int T,n,m; 
 31     scanf("%d",&T);
 32     while(T--)
 33     {
 34         scanf("%d%d",&n,&m);
 35         init(n,m);
 36         int p=gauss(n,m); 
 37         if(p==-1)
 38         {
 39             printf("no answer
");
 40             return 0; 
 41          } 
 42         if(p==-2)
 43         { 
 44                printf("have float answer
");
 45             return 0; 
 46         }
 47         printf("the num of free_x is %d
",p);
 48         print(m);
 49     }
 50     return 0;
 51 }
 52 //输出解的和,自由变元数量以及各个解 
 53 void print(int n)
 54 {
 55     //    若有小数解换为xd输出 
 56     int sum=0;
 57     for(int i=0;i<n;i++)
 58         sum+=x[i];
 59     printf("sum=%d
",sum); 
 60     for(int i=0;i<n;i++)
 61         printf("x%d=%d
",i+1,x[i]);
 62     return ;
 63 }
 64 //读入增广矩阵 
 65 void init(int n,int m)
 66 {
 67     clr(A);
 68     for(int i=0;i<n;i++)
 69         for(int j=0;j<=m;j++)
 70         scanf("%d",&A[i][j]); 
 71     clrdown(x);
 72     clr(free_x);
 73     return ;
 74 }
 75 int gauss(int n,int m)//输出-1是无解,-2是有小数解,>=0则是自由变元的数量和全为整数解 
 76 {
 77     int k,col,num=0,max_r,dou,max_x,LCM,ta,tb;
 78 //k为当前操作行,col为操作主元素所在列 
 79     for(k=0,col=0;k<n && col<m;k++,col++)
 80     {
 81         //若A[K][col]不为col列最大,则将k行与k+1到n-1行中A[i][col]绝对值最大的行交换
 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         //若k到n-1行A[i][col]全为0,则主元素指向当前行下一列的元素 
 96         if(A[k][col]==0)
 97         {
 98             k--;
 99             free_x[num++]=col;
100             //自由变元为当前col 
101             continue;
102         }
103         for(int i=k+1;i<n;i++)
104         if(A[i][col])
105         {
106             LCM=lcm(abs(A[k][col]),abs(A[i][col]));
107             ta=LCM/abs(A[i][col]);
108             tb=LCM/abs(A[k][col]);
109             if(A[k][col]*A[i][col]<0) tb=-tb;//若符号不同则取反 
110             for(int j=col;j<=m;j++)
111             {
112                     A[i][j]=A[i][j]*ta-A[k][j]*tb;
113                  // A[i][j]=((A[i][j]*ta-A[k][j]*tb)%mod+mod)%mod; //模mod矩阵的消元 
114             }
115         }
116     }
117     //k行及之后若有(0,0,0……,0,a)(a!=0)的行,则无解输出-1 
118     for(int i=k;i<n;i++)
119         if(A[i][col]!=0)
120             return -1;    
121     int temp;
122     //对自由变元的赋值,可有多种方式 
123     //若为小数解则换为xd; 
124     for(int i=0;i<num;i++)
125         x[free_x[i]]=0;
126     //int  xi,yi; exgcd需要 
127     for(int i=k-1,c=m-1;i>=0;c=m-1,i--)
128     {
129         temp=A[i][m];
130         while(x[c]!=-1)
131         {
132             if(A[i][c])
133                  temp-=x[c]*A[i][c]; 
134                 //temp=((temp-(x[c]*A[i][c])%mod)%mod+mod)%mod;//模mod矩阵的回代  
135             c--;
136         }
137         if(temp%A[i][c]!=0) return -2;
138         x[c]=temp/A[i][c]; 
139         /*exgcd(A[i][c],mod,xi,yi);
140         xi=(xi%mod+mod)%mod;
141         x[c]=(temp*xi%mod+mod)%mod;*/ //模mod 矩阵的x[i]的赋值 
142     }
143     return col-k;
144 }
145 int exgcd(int a,int b,int &x,int &y)
146 {
147     if(b==0)
148     {
149         x=1;
150         y=0;
151         return a;
152     }
153     else
154     {
155         int r=exgcd(b,a%b,y,x);
156         y-=x*(a/b);
157         return r;
158     }
159 }
160 int gcd(int a,int b)
161 {
162     int c;
163     while(b!=0)
164     {
165         c=a%b;
166         a=b;
167         b=c;
168     }
169     return a;
170 }
171 int lcm(int a,int b)
172 {
173     return a/gcd(a,b)*b;
174 }

Educational Codeforces Round 63 (Rated for Div. 2) F

https://codeforces.com/contest/1155/problem/F

#include<bits/stdc++.h>
#define clr(x) memset(x,0,sizeof(x))
#define cpy(x,y) memcpy(y,x,sizeof(x))
#define INF 0x3f3f3f3f
#define LL long long
#define fi first
#define se second
#define pb push_back
using namespace std;
const LL mod = 1000003;
const int N =2e2+10;
LL A[N][N];
LL a[N];
LL MOD(LL x){
    return (x%mod+mod)%mod;
}
LL qpow(LL x,LL n){
    LL res = 1;
    for(;n;n>>=1,x = MOD(x*x))
        if(n&1) res = MOD(res*x);
    return res;
}
int gauss(int n){
    LL d;
    int col = n;
    bool flag;
    for(int i=0;i<n;i++){
        if(A[i][i] == 0){
            flag = 0;
            for(int j=i+1;j<n;j++){
                if(A[j][i] != 0 ){
                    for(int k=i;k<=n;k++)
                        swap(A[j][k],A[i][k]);
                    flag = 1;
                    break;
                }
            }
            if(!flag){
                col--;
                continue;
            }
        }
        d = qpow(A[i][i],mod-2);
        for(int j=i;j<=n;j++)

            A[i][j] = MOD(A[i][j] * d);
        for(int j=0;j<n;j++){
            if(i!=j){
                d = A[j][i];
                for(int k=i;k<=n;k++){
                    A[j][k] = MOD(A[j][k] - MOD(d * A[i][k]));
                }
            }
        }
    }
    return col;
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    LL x;
    LL d;
    for(int i=0;i<=10;i++){
        cout<<"? "<<i<<endl;
        fflush(stdout);
        cin>>x;
        for(int j=0;j<=10;j++)
            A[i][j] = qpow(i,j);
        A[i][11] = x;
    }
    gauss(11);
    for(int i=0;i<=10;i++)
        a[i] = A[i][11];
    LL ans = -1;
    for(int i=0;i<mod;i++)
    {
        x = 0;
        for(int j = 10;j>=0;j--)
            x = MOD(MOD(x * i) + a[j]);
        if(x == 0)
            ans = i;
    }
    cout<<"! "<<ans<<endl;
}
原文地址:https://www.cnblogs.com/wujiechao/p/5863299.html