範例程式碼 uva10090

//uva10090
#include <iostream>
#include <cmath>
// 本題背後的數學理論:http://tutorial92.wordpress.com/2012/09/17/uva-10090-marbles-tutorial/

using namespace std;

// 求最大公因數的同時,用輾轉相除法的特性求出 n1 * m1 + n2 * m2 = gcd(n1, n2) 的 m1, m2 值
// (相關知識:https://zh.wikipedia.org/wiki/%E6%89%A9%E5%B1%95%E6%AC%A7%E5%87%A0%E9%87%8C%E5%BE%97%E7%AE%97%E6%B3%95)
long long int GCD(long long int a, long long int b, long long int *x, long long int *y) {
	// 確保 a 恆大於 b
	if(a < b) {
		long long int buf, *bufP;
		
		buf = a;
		a = b;
		b = buf;
		
		bufP = x;
		x = y;
		y = bufP;
	}
	
	// 輾轉相除法算完的條件
	if(b == 0) {
		*x = 1;
		*y = 0;
		return a;
	}

	long long int gcd, retX, retY;

	// 遞迴法求出最大公因數
	gcd = GCD(b, a % b, &retX, &retY);
	
	// 計算 m1, m2 值
	*x = retY;
	*y = retX - (a / b) * retY;

	return gcd;
}

int main() {
	long long int total, cost1, num1, cost2, num2, box1, box2;

	while(cin >> total) {
		if(total == 0)
			break;

		long long int gcd, bufBox1, bufBox2, myCeil, myFloor, myCost;

		// get input
		cin >> cost1 >> num1 >> cost2 >> num2;

		// get GCD
		gcd = GCD(num1, num2, &bufBox1, &bufBox2);
		
		// N 不整除 gcd 表示不管怎麼湊都湊不出來
		if(total % gcd != 0)
			cout << "failed" << endl;
		else {
			// 由 n1 * m1 + n2 * m2 = gcd(n1, n2) 還原回 n1 * m1 + n2 * m2 = N
			bufBox1 *= (total / gcd);
			bufBox2 *= (total / gcd);
			
			// ceil(-m1 * gcd / n2) <= t <= floor(m2 * gcd / n1) - 詳閱"本題背後的數學理論"
			myCeil = (long long int)ceil(-(double)bufBox1 * gcd / num2);
			myFloor = (long long int)floor((double)bufBox2 * gcd / num1);
			
			// ceil() > floor() 則 t 不存在
			if(myCeil > myFloor)
				cout << "failed" << endl;
			else {
				// cost = c1 * m1 + c2 * m2 = c1 * ( m1 + n2 / gcd * t ) + c2 * ( m2 – n1 / gcd * t)
				//		= c1 * m1 + c2 * m2 + t * (c1 * n2 / gcd – c2 * n1 / gcd)
				// 由於 c1 * m1 + c2 * m2 不影響結果,因此這部分便省略計算 - 算式細節詳閱"本題背後的數學理論"
				myCost = (cost1 * num2 / gcd) - (cost2 * num1 / gcd);
				
				// 最少的 box 數必在極端位置
				if(myCost * myCeil < myCost * myFloor) {
					box1 = bufBox1 + num2 / gcd * myCeil;
					box2 = bufBox2 - num1 / gcd * myCeil;
				}
				else {
					box1 = bufBox1 + num2 / gcd * myFloor;
					box2 = bufBox2 - num1 / gcd * myFloor;
				}
				
				// 輸出最終答案
				cout << box1 << ' ' << box2 << endl;
			}
		}
	}

	return 0;
}