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.\n");
      else if(t) printf("Multiple solutions.\n");
      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\n",a[n][n+1]);
      }
    }
return 0;
}

 

转载于:https://www.cnblogs.com/lmjer/p/9316375.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值