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

题意:有n 种装饰物,m 个已知条件,每个已知条件的描述如下:

p start end
a1, a2......ap (1<= ai <= n)
第一行表示从星期 start 到星期 end 一共生产了p 件装饰物 (工作的天数为end - start + 1 + 7*x, 加 7*x 是因为它可能生产很多周),第二行表示这 p 件装饰物的种类(可能出现相同的种类,即 ai = aj)。规定每件装饰物至少生产3 天,最多生产9 天。问每种装饰物需要生产的天数。如果没有解,则输出“Inconsistent data.”,如果有多解,则输出“Multiple solutions.”,如果只有唯一解,则输出每种装饰物需要生产的天数。
 
思路:高斯消元接同模方程组
设每种装饰物需要生产的天数为 xi(1<=i<=n)。每一个条件就相当于给定了一个方程式,假设生产1 类装饰物 a1 件、2 类装饰物 a2 件、i 类装饰物 ai 件所花费的天数为 b = end - star + 1 + 7 * x,则可以列出下列方程:
a1 * x1 + a2 * x2 +...an * xn = b (mod 7)
这样一共可以列出m 个方程式,然后使用高斯消元来解此方程组即可。
 
 
代码:
 #include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <math.h>
using namespace std; const int MAXN = 4e2;
const int mod = ;
bool free_x[MAXN];
int a[MAXN][MAXN];
int x[MAXN]; inline int gcd(int a, int b){
int t;
while(b != ){
t = b;
b = a % b;
a = t;
}
return a;
} inline int lcm(int a, int b){
return a / gcd(a, b) * b;
} //返回-1表示无解,0表示有唯一解,大于0表示无穷解并返回变元个数
int Gauss(int equ, int var){//equ为方程数,var为未知数个数
int i, j, k;
int max_r;//当前列绝对值最大的行
int col;//当前处理的列
int ta, tb;
int LCM;
int temp;
int free_x_num;
int free_index;
for(int i = ; i <= var; i++){
x[i] = ;
free_x[i] = true;//初始化全部为变元
}
for(k = , col = ; k < equ && col < var; k++, col++){
//枚举当前处理的行k
//找到当前col列元素绝对值最大的行与第k行交换
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){//与第k行交换
for(int j = k; j < var + ; j++){
swap(a[k][j], a[max_r][j]);
}
}
if(a[k][col] == ){//说明col列中第k行以下全是0了,则处理当前下一行
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) % mod + mod) % mod;
}
}
}
}
//无解的情况,化简的增广矩阵中存在(0,0,...1)这样的行(a!=0)
for(i = k; i < equ; i++){
if(a[i][col] != ) return -;
}
//无穷解的情况: 在var * (var + 1)的增广阵中出现(0, 0, ..., 0)这样的行,即说明没有形成严格的上三角阵.
//且出现的行数即为自由变元的个数.
if(k < var){
for(i = k - ; i >= ; i--){
// 第i行一定不会是(0, 0, ..., 0)的情况,因为这样的行是在第k行到第equ行.
// 同样,第i行一定不会是(0, 0, ..., a), a != 0的情况,这样的无解的.
free_x_num = ;//用于判断该行中的不确定的变元的个数,如果超过1个,则无法求解,它们仍然为不确定的变元.
for(j = ; j < var; j++){
if(a[i][j] && free_x[j]) free_x_num++, free_index = j;
}
if(free_x_num > ) continue;//无法求解出确定的变元
// 说明就只有一个不确定的变元free_index,那么可以求解出该变元,且该变元是确定的
temp = a[i][var];
for(j = ; j < var; j++){
if(a[i][j] != && j != free_index) temp -= a[i][j] * x[j] % mod;
temp = (temp % mod + mod) % mod;
}
x[free_index] = (temp / a[i][free_index]) % mod;//求出该变元
free_x[free_index] = ;//该变元已经确定,取消对应变元标记
}
return var - k;//自由变元有var-k个
}
//唯一解的情况: 在var * (var + 1)的增广阵中形成严格的上三角阵.
//计算出Xn-1, Xn-2 ... X0.
for(i = var - ; i >= ; i--){
temp = a[i][var];
for(j = i + ; j < var; j++){
if(a[i][j] != ) temp -= a[i][j] * x[j];
temp = (temp % mod + mod) % mod;
}
while(temp % a[i][i] != ) temp += mod;
x[i] = (temp /a[i][i]) % mod;
}
return ;
} int tran(char *s){
if(strcmp(s, "MON") == ) return ;
if(strcmp(s, "TUE") == ) return ;
if(strcmp(s, "WED") == ) return ;
if(strcmp(s, "THU") == ) return ;
if(strcmp(s, "FRI") == ) return ;
if(strcmp(s, "SAT") == ) return ;
return ;
} char s1[], s2[]; int main(void){
int n, m, k, t;
while(~scanf("%d%d", &n, &m)){
if(n + m == ) break;
memset(a, , sizeof(a));
for(int i = ; i < m; i++){
scanf("%d%s%s", &k, s1, s2);
a[i][n] = ((tran(s2) - tran(s1) + ) % mod + mod) % mod;//方程组的常数项
while(k--){
scanf("%d", &t);
t--;
a[i][t]++;
if(a[i][t] >= mod) a[i][t] %= mod;
}
}
int cnt = Gauss(m, n);//m为条件数目即方程数
if(cnt == ){
for(int i = ; i < n; i++){
if(x[i] <= ) x[i] += ;//题意要求每件物品最少生产3天,最多生产9天
printf("%d ", x[i]);
}
puts("");
}else if(cnt == -) puts("Inconsistent data.");
else puts("Multiple solutions.");
}
return ;
}

poj2947(高斯消元解同模方程组)的更多相关文章

  1. 【poj2947】高斯消元求解同模方程组【没有AC,存代码】

    题意: p start enda1,a2......ap (1<=ai<=n)第一行表示从星期start 到星期end 一共生产了p 件装饰物(工作的天数为end-start+1+7*x, ...

  2. POJ2947Widget Factory(高斯消元解同模方程)

    http://poj.org/problem?id=2947 题目大意:有n 种装饰物,m 个已知条件,每个已知条件的描述如下:p start enda1,a2......ap (1<=ai&l ...

  3. Poj 2947 widget factory (高斯消元解同模方程)

    题目连接: http://poj.org/problem?id=2947 题目大意: 有n种类型的零件,m个工人,每个零件的加工时间是[3,9],每个工人在一个特定的时间段内可以生产k个零件(可以相同 ...

  4. bzoj千题计划187:bzoj1770: [Usaco2009 Nov]lights 燈 (高斯消元解异或方程组+枚举自由元)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1770 a[i][j] 表示i对j有影响 高斯消元解异或方程组 然后dfs枚举自由元确定最优解 #in ...

  5. [置顶] hdu 4418 高斯消元解方程求期望

    题意:  一个人在一条线段来回走(遇到线段端点就转变方向),现在他从起点出发,并有一个初始方向, 每次都可以走1, 2, 3 ..... m步,都有对应着一个概率.问你他走到终点的概率 思路: 方向问 ...

  6. 【BZOJ】2466: [中山市选2009]树 高斯消元解异或方程组

    [题意]给定一棵树的灯,按一次x改变与x距离<=1的点的状态,求全0到全1的最少次数.n<=100. [算法]高斯消元解异或方程组 [题解]设f[i]=0/1表示是否按第i个点的按钮,根据 ...

  7. 【高斯消元解xor方程】BZOJ1923-[Sdoi2010]外星千足虫

    [题目大意] 有n个数或为奇数或为偶数,现在进行m次操作,每次取出部分求和,告诉你这几次操作选取的数和它们和的奇偶性.如果通过这m次操作能得到所有数的奇偶性,则输出进行到第n次时即可求出答案:否则输出 ...

  8. 【高斯消元解xor方程组】BZOJ2466-[中山市选2009]树

    [题目大意] 给出一棵树,初始状态均为0,每反转一个节点的状态,相邻的节点(父亲或儿子)也会反转,问要使状态均为1,至少操作几次? [思路] 一场大暴雨即将来临,白昼恍如黑夜!happy! 和POJ1 ...

  9. poj1830(高斯消元解mod2方程组)

    题目链接:http://poj.org/problem?id=1830 题意:中文题诶- 思路:高斯消元解 mod2 方程组 有 n 个变元,根据给出的条件列 n 个方程组,初始状态和终止状态不同的位 ...

随机推荐

  1. POJ1274(二分图最大匹配)

    The Perfect Stall Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 23356   Accepted: 104 ...

  2. 重新认识synchronized(上)

    synchronized在JDK5之前一直被称为重量级锁,是一个较为鸡肋的设计,而在JDK6对synchronized内在机制进行了大量显著的优化,加入了CAS,轻量级锁和偏向锁的功能,性能上已经跟R ...

  3. Mysql数据库服务器配置文件/etc/my.cnf的详细配置

    以下是 Mysql数 据库服务器配置文件 /etc/my.cnf的详细配置.应用场合是 InnoDB引擎, 4核 CPU, 32位SUSE.   [client] port        = 3306 ...

  4. 关于:cross_validation.scores

    # -*- coding: utf-8 -*- """ Created on Wed Aug 10 08:10:35 2016 @author: Administrato ...

  5. ffmpeg部分编译选项

    -enable-neon  (如果使用了arm公司提供的neon加速技术,则可以并行的读取多个元素.参考网址:http://www.cnblogs.com/hrlnw/p/3723072.html) ...

  6. 无法解决 equal to 操作中 "Chinese_PRC_CI_AS" 和 "Chinese_PRC_BIN" 之间的排序规则冲

    在两个数据库之间进行复合查询时有时会出现如下错误: 无法解决 equal to 操作中 "Chinese_PRC_CI_AS" 和 "Chinese_PRC_BIN&qu ...

  7. 基于cookie实现用户验证

    #!/usr/bin/env python import tornado.ioloop import tornado.web class IndexHander(tornado.web.Request ...

  8. C++数组对象和构造函数

    定义数组对象以后,对数组中的对象初始化的方式分为两种: 一种方式是在定义的时候用列表初始化 A a[5] = {A(1),A(2),A(3),A(4),A(5)}; 一种方式是在定义了数组对象以后,再 ...

  9. ???SpringMVC_03 利用SpringMVC提供的过滤器解决浏览器请求参数的乱码问题

    1 响应乱码问题 在启用mvc注解的配置中添加一个转换器配置 <?xml version="1.0" encoding="UTF-8"?> < ...

  10. resize和reserve的区别

    转自http://blog.csdn.net/jackywgw/article/details/6248342 首先必须弄清楚两个概念: 1.capacity 指容器在分配新的存储空间之前能存储的元素 ...