ALGO-109 貌似化學 逆矩陣
阿新 • • 發佈:2020-10-05
/* 演算法訓練 貌似化學 資源限制 時間限制: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 */ #include<iostream> #include<algorithm> #include<cmath> using namespace std; typedef long long ll; ll ans[4]; ll b[4]; ll c[4][4]; ll A[4][4]; //伴隨矩陣 ll gcd(ll a, ll b) { if(!b) return a; return gcd(b, a%b); } void fun() { //求伴隨矩陣(不求逆矩陣,因為可能出現分式,在計算的結果最後取最大公約數) for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) { //計算餘子式 int minr, maxr, minc, maxc; //row carry 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); A[i][j] = pow (-1, i + j) * (c[minr][minc] * c[maxr][maxc] - c[maxr][minc] * c[minr][maxc]); } //矩陣乘法 for(int i = 0; i < 3; i++) ans[i] = b[0]*A[0][i]+b[1]*A[1][i]+b[2]*A[2][i]; if(ans[1] < 0 || ans[2] < 0 || ans[0] < 0) ans[0] = -ans[0], ans[1] = -ans[1], ans[2] = -ans[2]; if(ans[1] < 0 || ans[2] < 0 || ans[0] < 0) cout << "NONE"; //不是都為負數,則不存在結果 else { ll tmp = gcd(ans[1], ans[2]); tmp = gcd(tmp, ans[0]); ans[1] /= tmp; ans[2] /= tmp; ans[0] /= tmp; cout << ans[0] << ' ' << ans[1] << ' ' << ans[2] << ' ' << (ans[0]*c[0][0]+ans[1]*c[1][0]+ans[2]*c[2][0])/b[0]; } } int main() { cin >> b[0] >> b[1] >> b[2]; for(int i = 0; i < 3; i++) for(int j = 0; j < 3; j++) cin >> c[i][j]; fun(); system("pause"); return 0; }