poj2947(高斯消元解线性同余方程)

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;

const int mod=7;
int n,m;

int a[300+10][300+10];
char c1[10],c2[10],c[10][10]={"1","MON","TUE","WED","THU","FRI","SAT","SUN"};//星期几

int get(char p[]){
    for (int i=1;i<=7;i++) if(!strcmp(p,c[i])) return i;
}

int guess(){
    int i,j;
    for (i=1,j=1;i<=m&&j<=n;j++){
        int k=i;
        while(k<=m&&!a[k][j]) k++;//找一个1...j前序数全为零的方程
        if(a[k][j]){
            for (int p=1;p<=n+1;p++) swap(a[k][p],a[i][p]);//把k行序数与i行交换保证了阶梯矩阵
            for (int h=i+1;h<=m;h++){
                if(a[h][j]){
                    int x=a[i][j],y=a[h][j];进行消元操作
                    for (int p=j/*i...j序数全为零故从j开始*/;p<=n+1;p++) a[h][p]=((a[h][p]*x-a[i][p]*y)%mod+mod)%mod;
                }
            }
            i++;
        }
    }
    for (int p=i;p<=m;p++) if(a[p][n+1]) return -1;检查是否有0=常数
    if(i<=n) return n-i+1;有几个不定元
    for (int x=n;x>=1;x--){
        for (int y=x+1;y<=n;y++){
            if(a[x][y]) a[x][n+1]=((a[x][n+1]-(a[x][y]*a[y][n+1]%mod))%mod+mod)%mod;    //a[x][y]*x=a[x][n+1] 带回消元
        }
        while(a[x][n+1]%a[x][x]!=0) a[x][n+1]+=7;
        a[x][n+1]=(a[x][n+1]/a[x][x])%mod;
    }
    return 0;
}

int main(){
    while(scanf("%d%d",&n,&m)&&n){
        int k,v;
        memset(a,0,sizeof(a));
        for (int i=1;i<=m;i++){
        scanf("%d%s%s",&k,c1,c2);
        a[i][n+1]=(get(c2)-get(c1)+8)%mod;
        for (int j=1;j<=k;j++) {scanf("%d",&v);a[i][v]++;}
        for (int j=1;j<=n;j++) a[i][j]%=7;
      }
      int t=guess();
      if(t==-1) printf("Inconsistent data.
");
      else if(t) printf("Multiple solutions.
");
      else {
        for (int i=1;i<=n;i++){
            if(a[i][n+1]<3) a[i][n+1]+=mod;
        }
        for (int i=1;i<n;i++) printf("%d ",a[i][n+1]);
        printf("%d
",a[n][n+1]);
      }
    }
return 0;
}
原文地址:https://www.cnblogs.com/lmjer/p/9316375.html