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

题目连接:

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

题目大意:

  有n种类型的零件,m个工人,每个零件的加工时间是[3,9],每个工人在一个特定的时间段内可以生产k个零件(可以相同种类,也可以不同种类),问每种零件生产一个出来需要的时间?

解题思路:

  给出的时间段是从周几到周几,并没有给出具体的时间段,因此在计算过程中要进行取模,还有就是对每个零件要在题目要求的范围内进行枚举。

ps:如果求出来的增广矩阵是n*n的,但是某个零件在[3,9]之间没有合理的解,也是无解的。

  1 #include <cmath>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <iostream>
  5 #include <algorithm>
  6 using namespace std;
  7 const int maxn = 310;
  8 int det[maxn][maxn], res[maxn], var, equ;
  9 char str[10][10] = {"","MON", "TUE", "WED", "THU", "FRI", "SAT" , "SUN"};
 10 int Day (char s[])
 11 {
 12     for (int i=1; i<8; i++)
 13         if (strcmp(s, str[i]) == 0)
 14             return i;
 15 }
 16 int gauss ()
 17 {
 18     int col, k;
 19     for (k=col=0; k<equ&&col<var; k++, col++)
 20     {
 21         int Max_i = k;
 22         for (int i=k+1; i<equ; i++)
 23             if (abs(det[i][col]) > abs(det[Max_i][col]))
 24                 Max_i = i;
 25         if (Max_i != k)
 26             for (int i=col; i<=var; i++)
 27                 swap (det[k][i], det[Max_i][i]);
 28         if (det[k][col] == 0)
 29         {
 30             k --;
 31             continue;
 32         }
 33         for (int i=k+1; i<equ; i++)
 34             if (det[i][col])
 35             {
 36                 int x = det[i][col];
 37                 int y = det[k][col];
 38                 for (int j=col; j<=var; j++)
 39                     det[i][j] = ((det[i][j]*y - det[k][j]*x) % 7 + 7) % 7;
 40             }
 41     }
 42     int temp = 0, i, j;
 43     for (i=0; i<equ; i++)
 44     {
 45         for (j=0; j<var; j++)
 46             if (det[i][j])
 47                 break;
 48         if (j == var)
 49         {
 50             if (det[i][j])
 51                 return 0;//增广矩阵无解
 52             else if (i < var)//增广矩阵存在不确定变元
 53                 temp ++;
 54         }
 55     }
 56     if (temp || var > equ)
 57         return 1;//增广矩阵存在不确定变元
 58 
 59     for (i=var-1; i>=0; i--)
 60     {
 61         temp = 0;
 62         for (j=i+1; j<var; j++)
 63             temp = (temp + det[i][j] * res[j]) % 7;
 64         for (j=3; j<10; j++)//枚举每个零件的加工时长
 65             if ((temp + det[i][i]*j)%7 == det[i][var])
 66             {
 67                 res[i] = j;
 68                 break;
 69             }
 70         if (j == 10)//当有某个零件的加工时长不在[3,9]之间,则不符合题意,无解
 71             return 0;
 72     }
 73     return 2;
 74 }
 75 int main ()
 76 {
 77     while (scanf ("%d %d", &var, &equ), var+equ)
 78     {
 79         int k, x;
 80         char st[maxn], et[maxn];
 81         memset (det, 0, sizeof(det));
 82         for (int i=0; i<equ; i++)
 83         {
 84             scanf ("%d %s %s", &k, st, et);
 85             while (k --)
 86             {
 87                 scanf ("%d", &x);
 88                 det[i][x-1] ++;
 89             }
 90             det[i][var] = Day(et) - Day(st) + 1;
 91         }
 92         for (int i=0; i<equ; i++)//这里一定要去次余,如果det[i][j]是7的倍数,在划成阶梯阵的过程中很有可能会错
 93             for (int j=0; j<=var; j++)
 94                 det[i][j] = (det[i][j] % 7 + 7) % 7;
 95         int ans = gauss();
 96         if (ans == 0)
 97             printf ("Inconsistent data.
");
 98         else if (ans == 1)
 99             printf ("Multiple solutions.
");
100         else
101             for (int i=0; i<var; i++)
102                 printf ("%d%c", res[i], i==var-1?'
':' ');
103     }
104     return 0;
105 }
本文为博主原创文章,未经博主允许不得转载。
原文地址:https://www.cnblogs.com/alihenaixiao/p/4631434.html