POJ2947 DAZE [Gauss]

题目是要求建立一个方程组:

(mat[1][1]*x[1] + mat[1][2]*x[2] + … + mat[1][n]*x[n])%7 =mat[1][n+1]

(mat[2][1]*x[1] + mat[2][2]*x[2] + … + mat[2][n]*x[n])%7 =mat[2][n+1]

(mat[m][1]*x[1] + mat[m][2]*x[2] + … + mat[m][n]*x[n])%7 =mat[m][n+1]

假设有解输出解得个数。假设无解Inconsistent data.无穷多组解Multiple solutions.

扯一句,什么时候无解?

系数矩阵的秩 不等于 增广矩阵的秩 时。反映在程序上就是:

for (i = row; i < N; i++)

{

if (a[i][M] != 0)

{

printf("Inconsistent data.\n");

}

}

什么时候无穷多解?

当增广矩阵的秩小于行列式的行数的时候。 反映在程序上就是:

if (row < M)

{

printf("Multiple solutions.\n");

}

好了。程序例如以下:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cstdlib>
using namespace std;
int m,n;//n lines
int M,N;
int a[333][333];
int times[333];
int ans[333];
int MOD=7;
int getday(char* s)
{
	if(strcmp(s,"MON")==0) return 1;
	if(strcmp(s,"TUE")==0) return 2;
	if(strcmp(s,"WED")==0) return 3;
	if(strcmp(s,"THU")==0) return 4;
	if(strcmp(s,"FRI")==0) return 5;
	if(strcmp(s,"SAT")==0) return 6;
	if(strcmp(s,"SUN")==0) return 7;
}

int extend_gcd(int A, int B, int &x, int &y)
{
    if (B == 0)
    {
        x = 1, y = 0;
        return A;
    }
    else
    {
        int r = extend_gcd(B, A%B, x, y);
        int t = x;
        x = y;
        y = t - A / B*y;
        return r;
    }
}

int lcm(int A, int B)
{
    int x = 0, y = 0;
    return A*B / extend_gcd(A, B, x, y);
}
void Guass()
{
    int i, j, row, col;
    for (row = 0, col = 0; row < N && col < M; row++, col++)
           {
        for (i = row; i < N; i++)
            if (a[i][col]) break;
        if (i == N)
                      {
            row--;
            continue;
                       }
        if (i != row)
            for (j = 0; j <= M; j++) swap(a[row][j], a[i][j]);
        for (i = row + 1; i < N; i++)
                     {
            if (a[i][col])
                                {
                int LCM = lcm(a[row][col], a[i][col]);//利用最小公倍数去化上三角
                int ch1 = LCM / a[row][col], ch2 = LCM / a[i][col];
                for (j = col; j <= M; j++)
                    a[i][j] = ((a[i][j] * ch2 - a[row][j] * ch1)%MOD + MOD)%MOD;
                                }
                     }
         }
   for (i = row; i < N; i++)//无解
        {
        if (a[i][M] != 0)
                      {
            printf("Inconsistent data.\n");
            return;
                      }
         }
   if (row < M)//无穷多解
        {
        printf("Multiple solutions.\n");
        return;
        }
        //唯一解时
   for (i = M - 1; i >= 0; i--)
        {
        int ch = 0;
        for (j = i + 1; j < M; j++)
                       {
            ch = (ch + ans[j] * a[i][j] % MOD)%MOD;
                       }
        int last = ((a[i][M] - ch)%MOD + MOD)%MOD;
        int x = 0, y = 0;
        int d = extend_gcd(a[i][i], MOD, x, y);
        x %= MOD;
        if (x < 0) x += MOD;
                ans[i] = last*x / d%MOD;
        if (ans[i] < 3) ans[i] += 7;
          }
   for (int i = 0; i < M; i++)
        {
        if (i == 0)
                 printf("%d", ans[i]);
        else
                 printf(" %d", ans[i]);
        }
   printf("\n");
}

int main()
{
	while(scanf("%d%d",&m,&n)!=EOF)
	{
		if(m==0&&n==0)
			break;
		M=m,N=n;
		memset(a,0,sizeof(a));
		memset(times,0,sizeof(times));
		memset(ans,0,sizeof(ans));
		for(int i=0;i<n;i++)
		{
			int prodnum;char str1[11],str2[11];
			scanf("%d%s%s",&prodnum,str1,str2);
			for(int j=0;j<prodnum;j++)
			{
				int tmp;
				scanf("%d",&tmp);
				a[i][tmp-1]++;
				a[i][tmp-1]%=MOD;
			}
			a[i][m]=(getday(str2)-getday(str1)+1+MOD)%MOD;
		}
		Guass();
	}
	return 0;
}
时间: 2024-08-27 01:54:12

POJ2947 DAZE [Gauss]的相关文章

[Gauss]POJ2947 Widget Factory

题意: 有n种小工具要加工,每种工具的加工时间为3到9天,给了m条加工记录.  每条记录 X s1 s2 分别代表 这个工人在s1到s2(前闭后闭)的时间里加工了X件小工具  下一行给出这X件小工具的种类 要求的是每件工具的加工时间 (唯一解:输出各个时间:无解:Inconsistent data.:多个解:Multiple solutions.) 可以列出同余方程组:∑(ai*xi)≡T(mod 7) (ai是此人加工第i件物品的个数,xi是第i件物品加工所需的时间,T是此人干活的时间) 这样

HDU 1588 Gauss Fibonacci(矩阵高速幂+二分等比序列求和)

HDU 1588 Gauss Fibonacci(矩阵高速幂+二分等比序列求和) ACM 题目地址:HDU 1588 Gauss Fibonacci 题意: g(i)=k*i+b;i为变量. 给出k,b,n,M,问( f(g(0)) + f(g(1)) + ... + f(g(n)) ) % M的值. 分析: 把斐波那契的矩阵带进去,会发现这个是个等比序列. 推倒: S(g(i)) = F(b) + F(b+k) + F(b+2k) + .... + F(b+nk) // 设 A = {1,1,

hdu 5755(GAuss 消元)

Gambler Bo Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 1152    Accepted Submission(s): 471Special Judge Problem Description Gambler Bo is very proficient in a matrix game. You have a N×M m

uva 1415 - Gauss Prime(高斯素数)

题目链接:uva 1415 - Gauss Prime 题目大意:给出一个a,b,表示高斯数a+bi(i=?2 ̄ ̄ ̄√,推断该数是否为高斯素数. 解题思路: a = 0 时.肯定不是高斯素数 a != 0时,推断a2+2b2是否为素数就可以. #include <cstdio> #include <cstring> #include <cmath> bool is_prime (int n) { int m = sqrt(n+0.5); for (int i = 2;

Hdoj 1588 Gauss Fibonacci 【矩阵快速幂】

Gauss Fibonacci Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2584 Accepted Submission(s): 1078 Problem Description Without expecting, Angel replied quickly.She says: "I'v heard that you'r a ver

矩阵十题【三】 HDU 1588 Gauss Fibonacci

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1588 题目大意:先要知道一组斐波那契数列 i 0 1 2 3 4 5 6 7 f(i) 0 1 1 2 3 5 8 13 下面给你一组数: k,b,n,M 现在知道一组公式g(i)=k*i+b:(i=0,1,2,3...n-1) 让你求出 f(g(i)) 的总和(i=01,2,3,...,n-1),比如给出的数据是2 1 4 100 2*0+1=1   f(1)=1 2*1+1=3   f(3)=2

HDU - 1588 Gauss Fibonacci (矩阵快速幂+二分求等比数列和)

Description Without expecting, Angel replied quickly.She says: "I'v heard that you'r a very clever boy. So if you wanna me be your GF, you should solve the problem called GF~. " How good an opportunity that Gardon can not give up! The "Prob

hdu 1588 Gauss Fibonacci(矩阵快速幂)

Gauss Fibonacci Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2090    Accepted Submission(s): 903 Problem Description Without expecting, Angel replied quickly.She says: "I'v heard that you'r

高斯消元法(Gauss Elimination)【超详解&amp;模板】

高斯消元法,是线性代数中的一个算法,可用来求解线性方程组,并可以求出矩阵的秩,以及求出可逆方阵的逆矩阵.高斯消元法的原理是:若用初等行变换将增广矩阵 化为 ,则AX = B与CX = D是同解方程组. 所以我们可以用初等行变换把增广矩阵转换为行阶梯阵,然后回代求出方程的解. 1.线性方程组 1)构造增广矩阵,即系数矩阵A增加上常数向量b(A|b) 2)通过以交换行.某行乘以非负常数和两行相加这三种初等变化将原系统转化为更简单的三角形式(triangular form) 注:这里的初等变化可以通过