POJ 2947 Widget Factory (高斯消元解同余方程组)
生活随笔
收集整理的這篇文章主要介紹了
POJ 2947 Widget Factory (高斯消元解同余方程组)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題意:N種物品,M條記錄,接寫來M行,每行有K,str1,str2,表示第i個記錄從星期str1到星期str2,做了K件物品,接下來的K個數為物品的編號。求做每個物品所需的時間,并且最后結果在3-9之間 ? 很容易想到高斯消元。但是是帶同余方程的高斯消元,開始建立關系的時候就要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; 但其實這道題用擴展gcd真的大材小用了,因為模數是固定的而且很小就是7,所以直接枚舉試就可以了~~ ?
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define MID(x,y) ((x+y)>>1)
using namespace std;
typedef long long LL;int gcd(int a, int b){return b ? gcd(b, a%b) : a;
}
int lcm(int a, int b){return a / gcd(a,b) * b;
}
const int MAX_EQU = 310;
typedef struct equation_set{int equ, var; //方程個數、變元個數,則增廣矩陣有equ行、var+1列.int mat[MAX_EQU][MAX_EQU+1]; //增廣矩陣int x[MAX_EQU]; //方程解向量bool free_x[MAX_EQU]; //判斷是否是不確定變元void init(int in_equ, int in_var);void debug();int gauss();
}EQU;
void equation_set::init(int in_equ, int in_var){equ = in_equ;var = in_var;memset(mat, 0, sizeof(mat));memset(x, 0, sizeof(x));memset(free_x, 1, sizeof(free_x));
}
void equation_set::debug(){for (int i = 0; i < equ; i ++){for (int j = 0; j < var; j ++)cout << mat[i][j] << " ";cout << mat[i][var] << endl;}
}
int equation_set::gauss(){int row = 0, col = 0;int max_row;while (row < equ && col < var){max_row = row;for (int i = row + 1; i < equ; i ++)if (abs(mat[i][col]) > abs(mat[max_row][col]))max_row = i;if (max_row != row){for (int j = 0; j <= var; j ++){int tmp = mat[row][j];mat[row][j] = mat[max_row][j];mat[max_row][j] = tmp;}}if (mat[row][col] == 0){col ++;continue;}//普通方程組行階梯化:for (int i = row + 1; i < equ; i ++){if (mat[i][col] != 0){int LCM = lcm(abs(mat[i][col]), abs(mat[row][col]));int ta = LCM / abs(mat[i][col]), tb = LCM / abs(mat[row][col]);if (mat[i][col] * mat[row][col] < 0) tb = -tb;for (int j = 0; j <= var; j ++)mat[i][j] = ((mat[i][j] * ta - mat[row][j] * tb) % 7 + 7) % 7;}}row++, col++;}//debug();//1. 無解for (int i = row; i < equ; i++){if (mat[i][col] != 0) return -1;}//2.無窮解(這里只是計算出了確定變元,對于多解的計算,需要枚舉自由變元的狀態或者其他方法求解.)if (row < var){return 1;}//3.唯一解for (int i = row - 1; i >= 0; i --){int tmp = (mat[i][var] % 7 + 7) % 7;for (int j = var - 1; j > i; j --)tmp = ((tmp - x[j] * mat[i][j]) % 7 + 7) % 7;while(tmp % mat[i][i] != 0)tmp += 7;x[i] = (tmp / mat[i][i] % 7 + 7) % 7;}return 0;
}
int week(char s[]){if (strcmp(s, "MON") == 0)return 1;else if (strcmp(s, "TUE") == 0)return 2;else if (strcmp(s, "WED") == 0)return 3;else if (strcmp(s, "THU") == 0)return 4;else if (strcmp(s, "FRI") == 0)return 5;else if (strcmp(s, "SAT") == 0)return 6;else if (strcmp(s, "SUN") == 0)return 7;
}
int main(){int n,m;while(scanf("%d%d", &n, &m) == 2){if (n + m == 0)break;EQU E;E.init(m, n);for (int i = 0; i < m; i ++){int k;char s1[10], s2[10];scanf("%d", &k);scanf("%s%s", s1, s2);E.mat[i][n] = (week(s2) - week(s1) + 1) % 7;for (int j = 0; j < k; j ++){int tmp;scanf("%d", &tmp);E.mat[i][tmp-1] ++;}for (int j = 0; j < n; j ++)E.mat[i][j] %= 7;}//E.debug();int p = E.gauss();if (p == -1){printf("Inconsistent data.\n");}else if (p == 1){printf("Multiple solutions.\n");}else{for (int i = 0; i < n; i ++)if(E.x[i] < 3)E.x[i] += 7;for (int i = 0; i < n - 1; i ++)printf("%d ", E.x[i]);printf("%d\n", E.x[n-1]);}}return 0;
}
?
轉載于:https://www.cnblogs.com/AbandonZHANG/archive/2013/02/10/4114216.html
總結
以上是生活随笔為你收集整理的POJ 2947 Widget Factory (高斯消元解同余方程组)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python: UTF8转换代码实例
- 下一篇: Asp.net内置对象之Cookies