PKU 2947 Widget Factory

题目:http://poj.org/problem?id=2947

题意:工人生产不同的部件需要不同的时间,最少需要3天,最多需要9天。
     现有给出n种部件和m条记录,每条记录包括该工人生产部件的总数k和他开始生产时间和结束时间(只给出是周几,不给出具体时间),之后给出这K个部件跟别所属的种类。
     最后求出生产这n种部件分别所需要的时间。

思路:高斯消元,设每种部件生产一个所需要的天数为xi, 每种部件的个数为ai(1<=i<=n), 所需天数为yj(1<=j<=m), 方程组为 a1*x1+a2*x2+…………an*xn=yj mod 7.
     需要注意的是,得出的结果必须在3--9之间~~~
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <stdlib.h>
using namespace std;
const int maxn=300;
int map[maxn+10][maxn+10];
char ch[7][5]={"MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN"};
int n, m, k, t, s, e;
char start[5], end[5];
int gcd(int a, int b)
{
	int tem;
	while (b)
	{
		tem=a%b, a=b, b=tem;
	}
	return a;
}
int lcm(int a, int b)
{
	return a*b/gcd(a, b);
}
int Gauss()
{
	int row, col, LCM, ta, tb;
	for (row=0, col=0; row<m, col<n; row++, col++)
	{
		int maxr=row;
		for (int i=row+1; i<m; i++) if (map[i][col]>map[row][col]) maxr=i;
		if (maxr!=row) for (int i=0; i<=n; i++) swap(map[maxr][i], map[row][i]);
		if (map[row][col]==0) {row--; continue;}
		for (int i=row+1; i<m; i++)
		{
			if (!map[i][col]) continue;
			LCM=lcm(map[row][col], map[i][col]);
			ta=LCM/map[row][col], tb=LCM/map[i][col];
			for (int j=col; j<=n; j++) map[i][j]=((map[row][j]*ta-map[i][j]*tb)%7+7)%7;
		}
	}
	for (int i=row; i<m; i++) if (map[i][n]) return -1;
	if (row<n) return 0;
	for (int i=n-1; i>=0; i--)
	{
		for (int j=i+1; j<n; j++) if (map[i][j]) map[i][n]=((map[i][n]-map[i][j]*map[j][n])%7+7)%7;
		while (map[i][n]%map[i][i]) map[i][n]+=7;
		map[i][n]=(map[i][n]/map[i][i])%7;
	}
	return 1;
}
int main()
{
	//freopen("in.txt", "r", stdin);
	while (scanf("%d %d", &n, &m)==2)
	{
		if (n==0&&m==0) break;
		memset(map, 0, sizeof(map));
		for (int i=0; i<m; i++)
		{
			scanf("%d %s %s", &k, start, end);
			for (int j=0; j<7; j++) 
			{
				if (strcmp(start, ch[j])==0) s=j;
				if (strcmp(end, ch[j])==0) e=j;
			}
			map[i][n]=(e-s+1+7)%7;
			for (int j=0; j<k; j++)
			{
				scanf("%d", &t);
				map[i][t-1]++;
			}
			for (int j=0; j<n; j++) map[i][j]=map[i][j]%7;
		}
		int flag=Gauss();
		if (flag==-1) printf("Inconsistent data.\n");
		else if (flag==0) printf("Multiple solutions.\n");
		else
		{
			for (int i=0; i<n-1; i++) 
			{
				if (map[i][n]<3) printf("%d ", map[i][n]+7);
				else printf("%d ", map[i][n]);
			}
			if (map[n-1][n]<3) printf("%d\n", map[n-1][n]+7);
			else printf("%d\n", map[n-1][n]);
		}
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值