zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    Java构造和解析Json数据的两种方法详解一
    使用json-lib进行Java和JSON之间的转换
    java 读取文件转换成字符串
    Jackson 框架,轻易转换JSON
    (转载)最黑的黑客米特尼克:多次耍FBI 终被高手擒
    (转载)Linux下IPTABLES防火墙的设定
    (转载)Linux下IPTABLES配置详解
    (转载)Linux上iptables防火墙的基本应用教程
    (转载)更好的重启nginx 服务器
    (转载)JavaScript中的Window窗口对象
  • 原文地址:https://www.cnblogs.com/wujiechao/p/5863299.html
Copyright © 2011-2022 走看看