POJ 2947 Widget Factory (高斯消元 判多解 无解 和解集 模7情况)
题意:
公司被吞并,老员工几乎全部被炒鱿鱼。一共有n种不同的工具,编号1-N(代码中是0—N-1), 每种工具的加工时间为3—9天 ,但是现在老员工不在我们不知道每种工具的加工时间,庆幸的是还保留着一些对工人制造工具的记录,对于每个老员工,他的记录包括,他开始工作的时间(在某个星期的星期几),被炒鱿鱼的时间(某个星期的星期几),在第几个星期不知道.....在这段时间里,他正好加工了k件物品,给出了这k件物品的编号。我们要做的就是通过这些记录,来确定每种工具的加工时间是多少。
分析:
对于每个记录,建立一个方程,所有的记录,建立为如下的方程:
(a[0][0]*X0 + a[0][1] *X1 + a[0][2]*X2+...........a[0][n-1]*Xn-1 ) %7= a[0][n]
(a[1][0]*X0 + a[1][1] *X1 + a[1][2]*X2+...........a[1][n-1]*Xn-1 ) %7= a[1][n]
................................................................................................................................
(a[m-1][0]*X0 + a[m-1][1] *X1 + a[m-1][2]*X2+...........a[m-1][n-1]*Xn-1 ) %7= a[m-1][n]
一共有m个记录,即有m个方程,有n个变量(表示n个物品,编号0-N-1),方程中的x0, x1, x2........xn-1,代表的是第i种工具加工需要多长时间
a[ i ] [ j ] (0<=j<=n-1) ,表示第i个方程中(i从0开始),编号为j的物品,加工的个数,即Xj, a[i][n] ,表示第i个方程中,加工完所有种类的工具,需要的时间,因为不知道开始时间和结束时间是在第几个星期,只知道星期几,所以有 %7.
然后处理一下列方程就行了。a[i][n] = 每个记录 的时间。
在做的过程中会遇到一些问题,可以参见注释,还有我的模板中加上那个判断有浮点数解的地方返回-2,会不对,貌似不应该加,这道题应该只有整数解。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#define LL __int64
const int maxn = +;
const int INF = <<;
using namespace std;
int equ, var, fn;
int a[maxn][maxn], x[maxn];
bool free_x[maxn]; int gcd(int a, int b)
{
return b==?a:gcd(b, a%b);
}
int lcm(int a, int b)
{
return a*b/gcd(a, b);
}
int Gauss()
{
int x_mo;
x_mo = ;
int i, j, k, max_r, col;
int ta, tb, LCM, tmp, fx_num;
int free_index;
col = ; for(k = ; k<equ && col<var; k++, col++)
{
max_r = k;
for(i = k+; i < equ; i++)
if(abs(a[i][col])>abs(a[max_r][col]))
max_r = i; if(max_r != k)
for(j = k; j < var+; j++)
swap(a[k][j], a[max_r][j]); if(a[k][col]==)
{
k--;
continue;
}
for(i = k+; i < equ; i++)
{
if(a[i][col] != )
{
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] < ) tb = -tb; for(j = col; j < var+; j++)
a[i][j] = ((a[i][j]*ta - a[k][j]*tb)%x_mo+x_mo)%x_mo;
}
}
}
for(i = k; i < equ; i++)
if(a[i][col] != )
return -; if(k < var)
return var-k; for(i = var-; i >= ; i--)
{
tmp = a[i][var];
for(j = i+; j < var; j++)
if(a[i][j] != )
tmp = ((tmp-a[i][j]*x[j])%x_mo+x_mo)%x_mo; if(a[i][i]==)
x[i] = ;
else
{
//if(tmp%a[i][i] != 0) return -2;
while(tmp%a[i][i]!=) tmp += x_mo;
x[i] = (tmp/a[i][i])%x_mo;
}
}
return ;
}
int check(char s[])
{
if(strcmp(s,"MON")==) return ;
else if(strcmp(s,"TUE")==) return ;
else if(strcmp(s,"WED")==) return ;
else if(strcmp(s,"THU")==) return ;
else if(strcmp(s,"FRI")==) return ;
else if(strcmp(s,"SAT")==) return ;
else return ;
}
int main()
{
int n, m, i, k;
char s1[], s2[];
while(~scanf("%d%d", &n, &m))
{
equ = m; var = n; //m个方程,n个未知数
if(n==&&m==) break;
memset(a, , sizeof(a));
memset(x, , sizeof(x));
memset(free_x, -, sizeof(free_x));
for(i = ; i < m; i++)
{
scanf("%d", &k);
getchar();
scanf("%s %s", s1, s2);
a[i][n] = ((check(s2)-check(s1)+)%+)%; //s1s2顺序不能乱,而且因为有负的所以需要这样处理
while(k--)
{
int tmp;
scanf("%d", &tmp);
tmp --; //因为a里面是从0开始的
a[i][tmp] ++;
a[i][tmp] %= ; //一定要对7取余,不然会wa,大概因为上面a[i][n]取余了,如果这里不取余会使方程无解吧。
}
}
fn = Gauss();
if(fn<)
printf("Inconsistent data.\n");
if(fn>)
printf("Multiple solutions.\n");
else if(fn==)
{
for(i = ; i < n; i++)
{
if(x[i]<=) x[i] += ; //注意题目说3——9天
if(i==n-)
printf("%d\n", x[i]);
else
printf("%d ", x[i]);
}
}
}
return ;
}
POJ 2947 Widget Factory (高斯消元 判多解 无解 和解集 模7情况)的更多相关文章
- Poj 2947 widget factory (高斯消元解同模方程)
题目连接: http://poj.org/problem?id=2947 题目大意: 有n种类型的零件,m个工人,每个零件的加工时间是[3,9],每个工人在一个特定的时间段内可以生产k个零件(可以相同 ...
- POJ 2947 2947 Widget Factory 高斯消元
给出组件的数量n,给出记录的数量m(n就是变元数量,m是方程数量).每一个记录代表一个方程,求每个组件的生产天数. 高斯消元即可 #include <cstdio> #include &l ...
- POJ 2947 Widget Factory(高斯消元)
Description The widget factory produces several different kinds of widgets. Each widget is carefully ...
- POJ 2947-Widget Factory(高斯消元解同余方程式)
题目地址:id=2947">POJ 2947 题意:N种物品.M条记录,接写来M行,每行有K.Start,End,表述从星期Start到星期End,做了K件物品.接下来的K个数为物品的 ...
- POJ2947Widget Factory(高斯消元解同模方程)
http://poj.org/problem?id=2947 题目大意:有n 种装饰物,m 个已知条件,每个已知条件的描述如下:p start enda1,a2......ap (1<=ai&l ...
- poj 2947 Widget Factory
Widget Factory 题意:有n件装饰品,有m组信息.(1 <= n ,m<= 300)每组信息有开始的星期和结束的星期(是在mod 7范围内的)并且还包括num种装饰品的种类(1 ...
- POJ 1830 开关问题 高斯消元,自由变量个数
http://poj.org/problem?id=1830 如果开关s1操作一次,则会有s1(记住自己也会变).和s1连接的开关都会做一次操作. 那么设矩阵a[i][j]表示按下了开关j,开关i会被 ...
- A - The Water Bowls POJ - 3185 (bfs||高斯消元)
题目链接:https://vjudge.net/contest/276374#problem/A 题目大意:给你20个杯子,每一次操作,假设当前是对第i个位置进行操作,那么第i个位置,第i+1个位置, ...
- POJ 1166 The Clocks 高斯消元 + exgcd(纯属瞎搞)
依据题意可构造出方程组.方程组的每一个方程格式均为:C1*x1 + C2*x2 + ...... + C9*x9 = sum + 4*ki; 高斯消元构造上三角矩阵,以最后一个一行为例: C*x9 = ...
随机推荐
- 开发中/listfile.jsp(11,31) quote symbol expected 这个错误
可能是因为11行33列,少了一个引号.
- SAP如何使用关于序列号的表
- shell date
.查看指定时间的时间戳 查看当前时间 #date +%s 查看指定时间 #date -d -- +%s #date -d +%s .将时间戳转换成date #date -d '1970-01-01 U ...
- HDU 5486 Difference of Clustering 图论
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5486 题意: 给你每个元素一开始所属的集合和最后所属的集合,问有多少次集合的分离操作,并操作和不变操 ...
- Linux安装python 2.7.9
1.下载python wget https://www.python.org/ftp/python/2.7.9/Python-2.7.9.tgz 2.解压.编译安装 tar -zxvf Python- ...
- JS事件(事件冒泡和事件捕获)
事件流:描述的是在页面中接收事件的顺序 事件冒泡:由最具体的元素接收,然后逐级向上传播至最不具体的元素的节点(文档) 事件捕获:最不具体的节点先接收事件,而最具体的节点应该是最后接收事件 DOM中:用 ...
- lintcode 中等题:subSets 子集
题目 子集 给定一个含不同整数的集合,返回其所有的子集 样例 如果 S = [1,2,3],有如下的解: [ [3], [1], [2], [1,2,3], [1,3], [2,3], [1,2], ...
- lintcode:两个数的和
题目 两数之和 给一个整数数组,找到两个数使得他们的和等于一个给定的数target. 你需要实现的函数twoSum需要返回这两个数的下标, 并且第一个下标小于第二个下标.注意这里下标的范围是1到n,不 ...
- 【PHPsocket编程专题(实战篇①)】php-socket通信演示
建立Socket连接至少需要一对套接字,其中一个运行于客户端,称为ClientSocket ,另一个运行于服务器端,称为ServerSocket . 套接字之间的连接过程分为三个步骤:服务器监听,客户 ...
- java:定义线程
Thread是java.lang包的类,默认导入. 进程:操作系统中的程序,多进程即同时运行多个程序.线程:程序中的流,多线程即程序中有多个流同时执行. 一个线程用一个线程对象表示 创建线程的方法: ...