Sicily 1099. Packing Passengers

已知乘客总数n,A类飞机的运输费用cA、客容量pA,B类飞机的运输费用cB、客容量pB,设A类飞机有A架,B类飞机有B架,问是否存在pA*A+pB*B=n;若存在,还要满足cA*A+cB*B最小;若存在多种解,A应尽可能的大。

根据拓展欧几里的定理,先求出gcd(pA,pB)并判断其能否整除n,不能则表示无解。若能,先求出a、b,使得pA*a+pB*b=gcd(pA,pB),可知A、B的特解为A= n/gcd(pA,pB)*a,B= n/ gcd(pA,pB)*b,故A、B的通解则满足A= A+pB/ gcd(pA,pB)*t,B=B -pA/ gcd(pA,pB)*t。另外因为A,B>=0,联系方程则有-A/(pB/ gcd(pA,pB))<=t<=B/(pA/ gcd(pA,pB))。当cA*pB-cB*pA<=0,即A类飞机的盈利性大于等于B类飞机时,A值应尽可能大,故t应该取最大值;反之,则B值应该尽可能地大,故t应该取最小值。

Run Time: 0.02sec

Run Memory: 304KB

Code Length: 1040Bytes

Submit Time: 2012-02-19 23:32:55

// Problem#: 1099
// Submission#: 1212195
// The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
// URI: http://creativecommons.org/licenses/by-nc-sa/3.0/
// All Copyright reserved by Informatic Lab of Sun Yat-sen University
#include <cstdio>
#include <cmath>
using namespace std;

void exEuclid( long long a, long long b, long long& x, long long& y, long long& gcd ) {
    if ( b == 0 ) {
        x = 1;
        y = 0;
        gcd = a;
    }
    else {
        exEuclid( b, a % b, y, x, gcd );
        y -= a / b * x;
    }
}

int main()
{
    long long n, cA, pA, cB, pB;
    long long A, B, gcd;
    int N, t;

    N = 1;
    while ( scanf( "%lld", &n ) && n ) {
        scanf( "%lld%lld%lld%lld", &cA, &pA, &cB, &pB );
        exEuclid( pA, pB, A, B, gcd );
        if ( n % gcd != 0 )
            printf( "Data set %d: cannot be flown\n", N++ );
        else {
            A *= n / gcd;
            B *= n / gcd;
            if ( cA * pB - cB * pA <= 0 )
                t = floor( (double)B / ( pA / gcd ) );
            else
                t = ceil( (double)-A / ( pB / gcd ) );
            A += pB / gcd * t;
            B -= pA / gcd * t;
            printf("Data set %d: %lld aircraft A, %lld aircraft B\n", N++, A, B );
        }
    }

    return 0;

}                                 


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值