POJ 2947-Widget Factory(高斯消元解同余方程式)
题目地址: id=2947">POJ 2947
题意:N种物品。M条记录,接写来M行,每行有K。Start,End,表述从星期Start到星期End,做了K件物品。接下来的K个数为物品的编号。
此题注意最后结果要调整到3-9之间。
思路:
非常easy想到高斯消元。
可是是带同余方程式的高斯消元,開始建立关系的时候就要MOD 7
解此类方程式时最后求解的过程要用到扩展gcd的思想,举个样例,假设最后得到的矩阵为:
1 1 4
0 6 4
则6 * X2 % 7= 4 % 7 则相当于6 * X2 + 7 * Y = 4,利用扩展gcd则可求出X2为3,则第一个方程为
X1 * 1 % 7 + 1*3 % 7 = 4 % 7 则相当于 X1 + 7 * Y = 1 得到X1=1。
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <sstream>
#include <algorithm>
#include <set>
#include <queue>
#include <stack>
#include <map>
using namespace std;
typedef long long LL;
const int inf=0x3f3f3f3f;
const double pi= acos(-1.0);
const double esp=1e-6;
const int MAXN=310;
int aug[MAXN][MAXN];<span style="background-color: rgb(255, 255, 255);">//增广矩阵行数为m,分别为0到m-1,列数为n+1,分别为0到n.</span>
int x[MAXN];//解集
int free_num;
int m,n;//m个方程。n个变元
int gcd(int a,int b) {
int r;
while(b!=0) {
r=b;
b=a%b;
a=r;
}
return a;
}
int lcm(int a,int b) {
return a/gcd(a,b)*b;
}
/*void Debug(void)
{
puts("");
int i,j;
for(i=0;i<m;i++){
for(j=0;j<n+1;j++){
cout << matrix[i][j] << " ";
}
cout << endl;
}
cout << endl;
}*/
int trans(char *str) {
if(strcmp(str,"MON")==0) return 1;
else if(strcmp(str,"TUE")==0) return 2;
else if(strcmp(str,"WED")==0) return 3;
else if(strcmp(str,"THU")==0) return 4;
else if(strcmp(str,"FRI")==0) return 5;
else if(strcmp(str,"SAT")==0) return 6;
else if(strcmp(str,"SUN")==0) return 7;
}
// 高斯消元法解方程组(Gauss-Jordan elimination).(-1表示无解。
//0表示唯一解。大于0表示无穷解。并返回自由变元的个数)
int Gauss() {
int i,j;
int row,col,max_r;// 当前这列绝对值最大的行;
int LCM;
int ta,tb;
int tmp;
for(row=0,col=0; row<m&&col<n; row++,col++) {
// 枚举当前处理的行.
// 找到该col列元素绝对值最大的那行与第row行交换.(为了在除法时减小误差)
max_r=row;
for(i=row+1; i<m; i++) {
if(abs(aug[i][col])>abs(aug[max_r][col]))
max_r=i;
}
if(max_r!=row) {
// 与第row行交换
for(j=row; j<n+1; j++)
swap(aug[row][j],aug[max_r][j]);
}
if(aug[row][col]==0) {
// 说明该col列第row行下面全是0了,则处理当前行的下一列.
row--;
continue;
}
for(i=row+1; i<m; i++) {
// 枚举要删去的行.
if(aug[i][col]!=0) {
LCM=lcm(abs(aug[i][col]),abs(aug[row][col]));
ta=LCM/abs(aug[i][col]);
tb=LCM/abs(aug[row][col]);
if(aug[i][col]*aug[row][col]<0) tb=-tb;//异号的情况是相加
for(j=col; j<n+1; j++) {
aug[i][j]=(((aug[i][j]*ta-aug[row][j]*tb)%7+7)%7);
}
}
}
}
//Debug();
// 1. 无解的情况: 化简的增广阵中存在(0, 0, ..., a)这种行(a != 0).
for(i=row; i<m; i++) {
if(aug[i][col]!=0) return -1;
}
// 2. 无穷解的情况: 在n * (n + 1)的增广阵中出现(0, 0, ..., 0)这种行,即说明没有形成严格的上三角阵.
// 且出现的行数即为自由变元的个数.
if(row<n){
return n-row;
}
// 3. 唯一解的情况: 在n * (n + 1)的增广阵中形成严格的上三角阵.
// 计算出Xn-1, Xn-2 ... X0.
for(i=n-1; i>=0; i--) {
tmp=aug[i][n];//等式右边的数
for(j=i+1; j<n; j++) {
if(aug[i][j]!=0) tmp-=aug[i][j]*x[j];//把已知的解带入。减去,仅仅剩下,一个未知的解
tmp=(tmp%7+7)%7;
}
while(tmp%aug[i][i]!=0)//外层每次循环都是为了求 a[i][i],由于它是每一个方程中唯一一个未知的变量(求该方程时)
tmp+=7;//由于天数不确定,而aug[i][i]必须得为整数才干够,周期为7
x[i]=(tmp/aug[i][i])%7;
}
return 0;
}
int main(void) {
int nn,mm,i,j,k;
int num;
char Start[5],End[5];
while(~scanf("%d %d",&nn,&mm)) {
if(nn==0&&mm==0) break;
n=m=0;
memset(aug,0,sizeof(aug));
for(i=0; i<mm; i++) {
scanf("%d",&k);
scanf("%s %s",Start,End);
aug[i][nn]=((trans(End)-trans(Start)+1)%7+7)%7;
for(j=1; j<=k; j++) {
scanf("%d",&num);
num--;
aug[i][num]++;
aug[i][num]%=7;//有反复的
}
}
m=mm;
n=nn;
free_num = Gauss();
if(free_num==0) {
for(i=0; i<n; i++)
if(x[i]<3)//依据题意,每一个零件的加工时间在3-9天.
x[i]+=7;
for(i=0; i<n-1; i++)
printf("%d ",x[i]);
printf("%d\n",x[i]);
} else if(free_num==-1)
puts("Inconsistent data.");
else
puts("Multiple solutions.");
}
return 0;
}
POJ 2947-Widget Factory(高斯消元解同余方程式)的更多相关文章
- 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 ...
- POJ2947Widget Factory(高斯消元解同模方程)
http://poj.org/problem?id=2947 题目大意:有n 种装饰物,m 个已知条件,每个已知条件的描述如下:p start enda1,a2......ap (1<=ai&l ...
- poj 2947 Widget Factory (高斯消元解同余方程组+判断无解、多解)
http://poj.org/problem?id=2947 血泪史: CE:poj的string类型要加string库,swap不能直接交换数组 WA: x[m-1]也有可能<3啊O(≧口≦) ...
- POJ 2947 Widget Factory(高斯消元)
Description The widget factory produces several different kinds of widgets. Each widget is carefully ...
- poj1830(高斯消元解mod2方程组)
题目链接:http://poj.org/problem?id=1830 题意:中文题诶- 思路:高斯消元解 mod2 方程组 有 n 个变元,根据给出的条件列 n 个方程组,初始状态和终止状态不同的位 ...
- poj1753(高斯消元解mod2方程组)
题目链接:http://poj.org/problem?id=1753 题意:一个 4*4 的棋盘,初始时上面放满了黑色或白色的棋子.对 (i, j) 位置进行一次操作后 (i, j), (i + 1 ...
- bzoj千题计划187:bzoj1770: [Usaco2009 Nov]lights 燈 (高斯消元解异或方程组+枚举自由元)
http://www.lydsy.com/JudgeOnline/problem.php?id=1770 a[i][j] 表示i对j有影响 高斯消元解异或方程组 然后dfs枚举自由元确定最优解 #in ...
- [置顶] hdu 4418 高斯消元解方程求期望
题意: 一个人在一条线段来回走(遇到线段端点就转变方向),现在他从起点出发,并有一个初始方向, 每次都可以走1, 2, 3 ..... m步,都有对应着一个概率.问你他走到终点的概率 思路: 方向问 ...
随机推荐
- ZOJ3714JavaBeans
#!/usr/bin/env python # encoding: utf-8 t = int(raw_input()) for i in range(t): n,k = [int(x) for x ...
- SVN异常处理(五)-状态小图标不见了
1.发现问题 装了Win10,再装了Office2016等一些最新软件后,发现SVN状态小图标竟然就不见了 2.分析问题 在Window系统中,当UAC启动时,有些应用程序的图标上会显示一个盾牌,像这 ...
- OFDM同步算法之Park算法
park算法代码 训练序列结构 T=[\(C\) \(D\) \(C^{*}\) \(D^{*}\)],其中C表示由长度为N/4的复伪随机序列PN,ifft变换得到的符号序列 \(C(n) = D(N ...
- HTML+CSS(12)
n CSS浮动和清除 Float:让元素浮动,取值:left(左浮动).right(右浮动). Clear:清除浮动,取值:left(清除左浮动).right(清除右浮动).both(同时清除上面的 ...
- html5——伸缩比例案例(携程)
1.有图片的盒子,最好是父盒子设置伸缩属性,a标签设置伸缩比例1,img标签宽度100% 2.不要见到父盒子就设置伸缩属性,而是根据子盒子是否占据一行,若是子盒子占据一行,那么只要给子盒子设置伸缩比例 ...
- TriAquae 是一款由国产的基于Python开发的开源批量部署管理工具
怀着鸡动的心情跟大家介绍一款国产开源运维软件TriAquae,轻松帮你搞定大部分运维工作!TriAquae 是一款由国产的基于Python开发的开源批量部署管理工具,可以允许用户通过一台控制端管理上千 ...
- tailf
功能说明:tailf命令几乎等同于tail -f,与tail -f不同的是,如果文件不增长,那么它不会去访问磁盘文件,也不会更改文件的访问时间.tailf命令在工作中的主要使命就是跟踪日志文件,首先将 ...
- eclipse版本和jdk的版本兼容问题
eclipse也是有版本的,当版本过低时,无法兼容高版本的jdk 项目中用的是jdk1.8,但是低版本的eclipse只能选到jdk1.7,导致java文件在编译的过程中,不识别1.8版本jdk的语法 ...
- Jenkins里jobs和workspace什么区别
https://segmentfault.com/q/1010000012575095/a-1020000012590560 简单的说,job 中保存的是项目是在 jenkins 上的配置.日志.构建 ...
- 如何从源码启动和编译IoTSharp
IoTSharp 项目是一个开源物联网平台,数据库使用PostgreSQL , 后端使用 Asp.Net Core 2.2 ,前端使用 vue-element-admin , 下面我们介绍如何启动项 ...