您的位置:首页 > 其它

POJ 2947 Widget Factory(高斯消元解同余方程组)

2016-09-12 11:14 465 查看
传送门

Widget Factory

Time Limit: 7000MSMemory Limit: 65536K
Total Submissions: 5663Accepted: 1961
DescriptionThe widget factory produces several different kinds of widgets. Each widget is carefully built by a skilled widgeteer. The time required to build a widget depends on its type: the simple widgets need only 3 days, but the most complex ones may need as many as 9 days.

The factory is currently in a state of complete chaos: recently, the factory has been bought by a new owner, and the new director has fired almost everyone. The new staff know almost nothing about building widgets, and it seems that no one remembers how many days are required to build each diofferent type of widget. This is very embarrassing when a client orders widgets and the factory cannot tell the client how many days are needed to produce the required goods. Fortunately, there are records that say for each widgeteer the date when he started working at the factory, the date when he was fired and what types of widgets he built. The problem is that the record does not say the exact date of starting and leaving the job, only the day of the week. Nevertheless, even this information might be helpful in certain cases: for example, if a widgeteer started working on a Tuesday, built a Type 41 widget, and was fired on a Friday,then we know that it takes 4 days to build a Type 41 widget. Your task is to figure out from these records (if possible) the number of days that are required to build the different types of widgets.

InputThe input contains several blocks of test cases. Each case begins with a line containing two integers: the number 1 ≤ n ≤ 300 of the different types, and the number 1 ≤ m ≤ 300 of the records. This line is followed by a description of the m records. Each record is described by two lines. The first line contains the total number 1 ≤ k ≤ 10000 of widgets built by this widgeteer, followed by the day of week when he/she started working and the day of the week he/she was fired. The days of the week are given bythe strings `MON’, `TUE’, `WED’, `THU’, `FRI’, `SAT’ and `SUN’. The second line contains k integers separated by spaces. These numbers are between 1 and n , and they describe the diofferent types of widgets that the widgeteer built. For example, the following two lines mean that the widgeteer started working on a Wednesday, built a Type 13 widget, a Type 18 widget, a Type 1 widget, again a Type 13 widget,and was fired on a Sunday.

4 WED SUN

13 18 1 13

Note that the widgeteers work 7 days a week, and they were working on every day between their first and last day at the factory (if you like weekends and holidays, then do not become a widgeteer!).

The input is terminated by a test case with n = m = 0 . OutputFor each test case, you have to output a single line containing n integers separated by spaces: the number of days required to build the different types of widgets. There should be no space before the first number or after the last number, and there should be exactly one space between two numbers. If there is more than one possible solution for the problem, then write `Multiple solutions.’ (without the quotes). If you are sure that there is no solution consistent with the input, then write `Inconsistent data.’(without the quotes). Sample Input2 3
2 MON THU
1 2
3 MON FRI
1 1 2
3 MON SUN
1 2 2
10 2
1 MON TUE
3
1 MON WED
3
0 0Sample Output8 3
Inconsistent data.HintHuge input file, ‘scanf’ recommended to avoid TLE.

题目大意:

这个题目的意思还是很难懂的,大体上就是说:有一个工厂生产有 n 中不同的装饰品,每个装饰品的生产时间是 t(3≤t≤9) 天, 因为一些原因

这个工厂换了一个老板,而这个老板几乎将所有的员工都解散了,所以招来的这些新的员工不熟悉每个装饰品的生产时间,现在有 m 个条件,

让你根据这 m 个条件来推测出每个装饰品的生产时间:这 m 个时间的描述如下:

首先给了一个整数 p 和两个字符串st 和 end(星期几到星期几)表示的是在 周 st 到 周 end 内(可能有很多周)生产了 p 件

装饰品,第二行输入的是装饰品的种类 val[i],可能有相同的装饰品也就是存在 val[i] == val[j] 的情况。如果有唯一解的时候输出解,

没有解输出”Inconsistent data.”,有多解输出”Multiple solutions.”

解题思路:

首先我们可以根据题目大意,列出一系列的同余方程组:我们设每个装饰品的生产时间是 xi,那么就有 n 个 xi,然后给定的 m 个条件

就是相当于有 m 个方程,假设生产第 i 类的商品有 ai 件,那么满足方程:

a0∗x0+a1∗x1+...+an−1∗xn−1 = (end−st+1)MOD 7

….

会有 m 个这样的方程,然后根据高斯消元就可以解决了。

My Code:

/**
2016 - 09 - 12 上午
Author: ITAK

Motto:

今日的我要超越昨日的我,明日的我要胜过今日的我,
以创作出更好的代码为目标,不断地超越自己。
**/

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <queue>
#include <algorithm>
#include <set>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const int INF = 1e9+5;
const int MAXN = 400+5;
const int MOD = 7;
const double eps = 1e-7;
const double PI = acos(-1);
using namespace std;
LL Scan_LL()///输入外挂
{
LL res=0,ch,flag=0;
if((ch=getchar())=='-')
flag=1;
else if(ch>='0'&&ch<='9')
res=ch-'0';
while((ch=getchar())>='0'&&ch<='9')
res=res*10+ch-'0';
return flag?-res:res;
}
int Scan_Int()///输入外挂
{
int res=0,ch,flag=0;
if((ch=getchar())=='-')
flag=1;
else if(ch>='0'&&ch<='9')
res=ch-'0';
while((ch=getchar())>='0'&&ch<='9')
res=res*10+ch-'0';
return flag?-res:res;
}
void Out(LL a)///输出外挂
{
if(a>9)
Out(a/10);
putchar(a%10+'0');
}
int equ, var;///equ个方程 var个变量
int a[MAXN][MAXN];///增广矩阵
int x[MAXN];///解集
int x_i[MAXN];
int free_x[MAXN];///判断是不是自由变元
int free_num;///自由变元的个数
inline int GCD(int m, int n)
{
if(n == 0)
return m;
return GCD(n, m%n);
}
inline int LCM(int aa, int bb)
{
return aa/GCD(aa,bb)*bb;
}
void Exgcd(int aa, int bb, int &xx, int &yy)
{
if(bb == 0)
{
xx = 1;
yy = 0;
return;
}
int xx1, yy1;
Exgcd(bb, aa%bb, xx1, yy1);
xx = yy1;
yy = xx1 - (aa/bb)*yy1;
}
void Debug()
{
puts("");
cout<<"+++++++++++++++++++++++++++分界线++++++++++++++++++++++++++++++"<<endl;
for(int i=0; i<equ; i++)
{
for(int j=0; j<var+1; j++)
{
cout<<a[i][j]<<" ";
}
cout<<endl;
}
cout<<"+++++++++++++++++++++++++++分界线++++++++++++++++++++++++++++++"<<endl;
puts("");
}
int Gauss()
{
int Max_r;///当前列绝对值最大的存在的行
///col:处理当前的列
int row,col = 0;
int free_x_num;
int free_index;
free_num = 0;
for(int i=0; i<=var; i++)
{
x[i] = 0;
free_x[i] = 1;
}
for(row=0; row<equ&&col<var; row++,col++)
{
Max_r = row;
for(int i=row+1; i<equ; i++)
if(abs(a[i][col]) > abs(a[Max_r][col]))
Max_r = i;
if(a[Max_r][col] == 0)
{
free_x[col] = 1;
x_i[free_num++] = col;
}
if(Max_r != row)
for(int i=0; i<var+1; i++)
swap(a[row][i], a[Max_r][i]);

if(a[row][col] == 0)
{
row--;
continue;
}
for(int i=row+1; i<equ; i++)
{
if(a[i][col])
{
int lcm = LCM(abs(a[i][col]), abs(a[row][col]));
int tp1=lcm/abs(a[i][col]), tp2=lcm/abs(a[row][col]);
if(a[row][col]*a[i][col] < 0)
tp2 = -tp2;
for(int j=col; j<var+1; j++)
a[i][j] = ( (tp1*a[i][j]-tp2*a[row][j]) % MOD + MOD ) % MOD;
}
}
}
for(int i=row; i<equ; i++)
if(a[i][col])
return -1;///无解
if(row < var)
return var - row;///自由变元的个数
///回代
for(int i=var-1; i>=0; i--)
{
int tmp = a[i][var] % MOD;
for(int j=i+1; j<var; j++)
if (a[i][j])
tmp = ((tmp - a[i][j]*x[j]) % MOD + MOD) % MOD;
while(tmp % a[i][i])
tmp += MOD;
x[i] = (tmp/a[i][i]) % MOD;
if(x[i] < 3)
x[i] += MOD;
}
return 0;///唯一解
}

char st[20], end1[20];
int Solve1(char str[])
{
if(strcmp(str, "MON") == 0)
return 1;
if(strcmp(str, "TUE") == 0)
return 2;
if(strcmp(str, "WED") == 0)
return 3;
if(strcmp(str, "THU") == 0)
return 4;
if(strcmp(str, "FRI") == 0)
return 5;
if(strcmp(str, "SAT") == 0)
return 6;
if(strcmp(str, "SUN") == 0)
return 7;
}

int main()
{
int n, m;
while(~scanf("%d%d",&n,&m))
{
if(n==0 && m==0)
break;
equ = m;
var = n;
memset(a, 0, sizeof(a));
memset(x, 0, sizeof(x));
for(int i=0; i<m; i++)
{
int k;
scanf("%d%s%s",&k,st,end1);
a[i][var] = (Solve1(end1)-Solve1(st)+8) % MOD;
a[i][var] = (a[i][var] % MOD + MOD) % MOD;
for(int j=0; j<k; j++)
{
int val;
scanf("%d",&val);
a[i][val-1]++;
a[i][val-1] %= MOD;
}
}
int tmp = Gauss();
///Debug();
if(tmp == -1)
puts("Inconsistent data.");
else if(tmp > 0)
puts("Multiple solutions.");
else
{
for(int i=0; i<var; i++)
{
if(i == var-1)
printf("%d\n",x[i]);
else
printf("%d ",x[i]);
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: