题目链接:https://vjudge.net/problem/POJ-2947
题意:转换题意后就是已知m个同余方程,求n个变量。
思路:
值得学习的是这个模板里消元用到lcm的那一块。注意题目输出的答案在[3,9]之间。
AC代码:
#include<cstdio> #include<algorithm> #include<cstring> #include<cmath> #include<cstdlib> using namespace std; const int maxn=305; int n,m,a[maxn][maxn],x[maxn]; char s1[10],s2[10]; int gcd(int a,int b){ return b?gcd(b,a%b):a; } int lcm(int a,int b){ return a/gcd(a,b)*b; //先除后乘 } // 高斯消元法解方程组(Gauss-Jordan elimination).( //-1表示无解,0表示唯一解,大于0表示无穷解,并返回自由变元的个数) //有equ个方程,var个变元。增广矩阵行数为equ,分别为0到equ-1,列数为var+1,分别为0到var. int Gauss(int equ,int var){ int k,max_r,col=0,ta,tb,LCM,temp; for(int i=0;i<var;++i){ x[i]=0; } for(k=0;k<equ&&col<var;++k,++col){ max_r=k; //找系数绝对值最大的那一行与第k行交换 for(int i=k+1;i<equ;++i){ if(abs(a[i][col])>abs(a[max_r][col])) max_r=i; } if(max_r!=k){ for(int i=col;i<var+1;++i) swap(a[max_r][i],a[k][i]); } if(!a[k][col]){ --k; continue; } for(int i=k+1;i<equ;++i){ if(!a[i][col]) continue; LCM=lcm(abs(a[i][col]),abs(a[k][col])); ta=LCM/abs(a[i][col]); tb=LCM/abs(a[k][col]); if(a[i][col]*a[k][col]<0) tb=-tb; //异号的情况是相加 for(int j=col;j<var+1;++j){ a[i][j]=((a[i][j]*ta-a[k][j]*tb)%7+7)%7; } } } //无解的情况 for(int i=k;i<equ;++i){ if(a[i][col]) return -1; } //无穷解的情况 if(k<var){ return var-k; //返回自由变元的个数 } //唯一解的情况,增广矩阵中形成严格的上三角阵 for(int i=var-1;i>=0;--i){ temp=a[i][var]; for(int j=i+1;j<var;++j){ if(!a[i][j]) continue; temp-=a[i][j]*x[j]; temp=(temp%7+7)%7; } while(temp%a[i][i]!=0) temp+=7; x[i]=(temp/a[i][i])%7; } return 0; } int tran(char *s){ if(strcmp(s,"MON")==0) return 1; else if(strcmp(s,"TUE")==0) return 2; else if(strcmp(s,"WED")==0) return 3; else if(strcmp(s,"THU")==0) return 4; else if(strcmp(s,"FRI")==0) return 5; else if(strcmp(s,"SAT")==0) return 6; else return 7; } int main(){ while(scanf("%d%d",&n,&m),n||m){ memset(a,0,sizeof(a)); for(int i=0;i<m;++i){ int k; scanf("%d%s%s",&k,s1,s2); a[i][n]=((tran(s2)-tran(s1)+1)%7+7)%7; while(k--){ int t; scanf("%d",&t); --t; ++a[i][t]; a[i][t]%=7; } } int ans=Gauss(m,n); if(ans==0){ for(int i=0;i<n;++i) if(x[i]<=2) x[i]+=7; for(int i=0;i<n-1;++i) printf("%d ",x[i]); printf("%d ",x[n-1]); } else if(ans==-1){ printf("Inconsistent data. "); } else{ printf("Multiple solutions. "); } } return 0; }