//t的值要使得costA * x + costB * y 最小,如果有多个值,则取令x最大的t //上式子可以改写成(x+(capB/gcd)*t)*costA+(y-(capA/gcd)*t)*costB ==> ((costA*capB-capA*costB)*t)/gcd + capA * x + capB*y 于是,当costA*capB-capA*costB<0,t应取最大值; 当costA*capB-capA*costB>0,t应取最小值; //当costA*capB-capA*costB=0,应选择较大的X值,显然 capB/gcd总是大于0的,所以t选择最大值,X取得更大值 #include <cstdio> #include <cmath> using namespace std; long long extendEuclid(long long a,long long b,long long& gcd,long long& x,long long& y)//扩展欧几里德算法 { if (!b) { gcd = a; x = 1; y = 0; } else { extendEuclid(b,a%b,gcd,y,x); y -= x*(a/b); } return gcd; } int main() { long long sum; int Case=1,t; while(scanf("%lld",&sum),sum) { long long costA,costB,capA,capB; long long x,y; scanf("%lld%lld%lld%lld",&costA,&capA,&costB,&capB); long long gcd=extendEuclid(capA,capB,gcd,x,y); //求得(capA * x) + (capB * y) = gcd(capA,capB)的x,y,gcd值 if (sum%gcd!=0) //当sum不是gcd的倍数,无整数解 { printf("Data set %d: cannot be flown/n",Case++); continue; } x=x*sum/gcd; //求得(capA * x) + (capB * y) = sum的x,y的其中一组解 y=y*sum/gcd; int tmin=(int)ceil((double)(-x)*gcd/capB); //所有解表示为X1 = x+(capB/gcd)*t, Y1 = y-(pasA/gcd)*t;分别令X1,Y1等于0 int tmax=(int)floor((double)(y)*gcd/capA); long long delta=costA*capB-costB*capA; int t=delta<=0?tmax:tmin; x=x+capB/gcd*t; y=y-capA/gcd*t; printf("Data set %d: %lld aircraft A, %lld aircraft B/n",Case++,x,y); } return 0; }