模线性方程组
题目链接:http://poj.org/problem?id=2947
有m条记录,n个零件,那么就是m个方程,n个未知数,然后所花的天数和在工厂呆的天数对7同余,也就是求解一个模线性方程组。
代码:
#include<bits/stdc++.h>
#define MAXN 310
#define N 310
#define MOD 7
using namespace std;
int a[N][N];//增广矩阵
int x[N];//解集
bool freeX[N];//标记是否为自由变元
int GCD(int a,int b){
return !b?a:GCD(b,a%b);
}
int LCM(int a,int b){
return a/GCD(a,b)*b;
}
int Gauss(int equ,int var){//返回自由变元个数
/*初始化*/
for(int i=0;i<=var;i++){
x[i]=0;
freeX[i]=true;
}
/*转换为阶梯阵*/
int col=0;//当前处理的列
int row;//当前处理的行
for(row=0;row<equ&&col<var;row++,col++){//枚举当前处理的行
int maxRow=row;//当前列绝对值最大的行
for(int i=row+1;i<equ;i++){//寻找当前列绝对值最大的行
if(abs(a[i][col])>abs(a[maxRow][col]))
maxRow=i;
}
if(maxRow!=row){//与第row行交换
for(int j=row;j<var+1;j++)
swap(a[row][j],a[maxRow][j]);
}
if(a[row][col]==0){//col列第row行以下全是0,处理当前行的下一列
row--;
continue;
}
for(int i=row+1;i<equ;i++){//枚举要删去的行
if(a[i][col]!=0){
int lcm=LCM(abs(a[i][col]),abs(a[row][col]));
int ta=lcm/abs(a[i][col]);
int tb=lcm/abs(a[row][col]);
if(a[i][col]*a[row][col]<0)//异号情况相加
tb=-tb;
for(int j=col;j<var+1;j++) {
a[i][j]=((a[i][j]*ta-a[row][j]*tb)%MOD+MOD)%MOD;
}
}
}
}
/*求解*/
//无解:化简的增广阵中存在(0,0,...,a)这样的行,且a!=0
for(int i=row;i<equ;i++)
if (a[i][col]!=0)
return -1;
//无穷解: 在var*(var+1)的增广阵中出现(0,0,...,0)这样的行
int temp=var-row;//自由变元有var-row个
if(row<var)//返回自由变元数
return temp;
//唯一解: 在var*(var+1)的增广阵中形成严格的上三角阵
for(int i=var-1;i>=0;i--){//计算解集
int temp=a[i][var];
for(int j=i+1;j<var;j++){
if(a[i][j]!=0)
temp-=a[i][j]*x[j];
temp=(temp%MOD+MOD)%MOD;//取模
}
while(temp%a[i][i]!=0)//外层每次循环都是求a[i][i],它是每个方程中唯一一个未知的变量
temp+=MOD;//a[i][i]必须为整数,加上周期MOD
x[i]=(temp/a[i][i])%MOD;//取模
}
return 0;
}
//
int sts(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 if(strcmp(s,"SUN")==0) return 7;
}
char s1[5], s2[5];
int main()
{
int n, m;
int equ, var;
while(~scanf("%d%d",&n,&m) && (n+m))
{
memset(a,0,sizeof(a));
equ = m;
var = n;
for(int i = 0; i < m; i++)
{
int k;
scanf("%d%s%s",&k,s1,s2);
a[i][var] = ((sts(s2)-sts(s1)+1)%7 + 7)%7;
for(int j = 0; j < k; j++){
int tp;
scanf("%d",&tp);
tp--;
a[i][tp]++;
a[i][tp]%=7;
}
}
int freeNum = Gauss(equ,var);
if(freeNum == -1)
{
printf("Inconsistent data.\n");
}
else if(freeNum > 0)
{
printf("Multiple solutions.\n");
}
else if(freeNum == 0)
{
for(int i = 0; i < var; i++){
if(x[i] <= 2) printf("%d ",x[i]+7);
else printf("%d ",x[i]);
}
printf("\n");
}
}
return 0;
}
京公网安备 11010502036488号