試題 算法訓練 貌似化學
資源限制
時間限制:1.0s 內存限制:256.0MB
問題描述
現在有a,b,c三種原料,如果他們按x:y:z混合,就能產生一種神奇的物品d。
當然不一定只產生一份d,但a,b,c的最簡比一定是x:y:z
現在給你3種可供選擇的物品:
每個物品都是由a,b,c以一定比例組合成的,求出最少的物品數,使得他們能湊出整數個d物品(這裏的最少是指三者個數的總和最少)
輸入格式
第一行三個整數,表示d的配比(x,y,z)
接下來三行,表示三種物品的配比,每行三個整數(<=10000)。
輸出格式
四個整數,分別表示在最少物品總數的前提下a,b,c,d的個數(d是由a,b,c配得的)
目標答案<=10000
如果不存在滿足條件的方案,輸出NONE
樣例輸入
3 4 5
1 2 3
3 7 1
2 1 2
樣例輸出
8 1 5 7
實現思路
假設已經知道了答案x, y , z;
存在這樣的關係
那麼 (x y z) 其實就可以通過逆矩陣求得
實現代碼
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
ll a[4][4], b[3][3], c[3], d[3];
ll gcd(ll a, ll b) { // 歐幾里得求解最大公因子
if (a < b) swap(a, b);
if (b == 0) return a;
else return gcd(b, a % b);
}
void count() {
// 求逆矩陣
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
int minc, maxc, minr, maxr;
minc = min((i + 1) % 3, (i + 2) % 3), maxc = max((i + 1) % 3, (i + 2) % 3);
minr = min((j + 1) % 3, (j + 2) % 3), maxr = max((j + 1) % 3, (j + 2) % 3);
b[i][j] = pow (-1, i + j) * (a[minr][minc] * a[maxr][maxc] - a[maxr][minc] * a[minr][maxc]);
}
}
//求解待解矩陣
for (int i = 0; i < 3; i++) d[i] = b[0][i] * c[0] + b[1][i] * c[1] + b[2][i] * c[2];
if (d[0] < 0 || d[1] < 0 || d[2] < 0) d[0] = -d[0], d[1] = -d[1], d[2] = -d[2];
if (d[1] < 0 || d[2] < 0) cout << "NONE" << endl; // 若存在不同號,則現實中不存在負數的量,即不存在
else {
ll temp = gcd(d[0], d[1]); temp = gcd(temp, d[2]);
ll ans = 0;
for (int i = 0; i < 3; i++) d[i] /= temp;
for (int i = 0; i < 3; i++) ans += d[i] * a[i][0];
ans /= c[0];
cout << d[0] << " " << d[1] << " " << d[2] << " " << ans << endl;
}
}
int main() {
for (int i = 0; i < 3; i++) cin >> c[i];
for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) cin >> a[i][j];
count();
return 0;
}