virtual hust 2013.6.21 NEFU 挑战编程----数论 G

题目:Marbles

思路: 扩展欧几里得。

      由于公式套出来的答案x,y,如果是(x*c)%b的话,求的是满足条件的x最接近于0的那组解,所以根据两种box的单位运输价值来判断到底是取x越小越好还是取y越小越好

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cmath>
using namespace std;
long long one,two,tag;
long long c1,c2,n1,n2,n;
void one_first()
{
    one=n/n1,two=0;
    int left=n-n1*one;
    while(left%n2!=0)
    {
        left+=n1;
        one--;
        two++;
        if(one<0)
        {
            tag=0;
            break;
        }
    }
}
void two_first()
{
    one=0,two=n/n2;
    int left=n-two*n2;
    while(left%n1!=0)
    {
        two--;
        one++;
        left+=n2;
        if(two<0)
        {
            tag=0;
            break;
        }
    }
}
int main()
{
    while(scanf("%lld",&n)!=EOF,n)
    {
        scanf("%lld%lld",&c1,&n1);
        scanf("%lld%lld",&c2,&n2);
        tag=1;
        if(n1*c2-n2*c1>0)
        {
            one_first();
        }
        else if(n1*c2==n2*c1)
        {
            if(n1<n2)
                one_first();
            else
                two_first();
        }
        else
            two_first();
        if(tag)
            printf("%lld %lld
",one,two);
        else
            printf("failed
");
    }
    return 0;
}
开始写的TLE的暴力code
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <iostream>
#include <cstring>
using namespace std;
long long gcd(long long a,long long b)
{
    if(b==0)
        return a;
    return gcd(b,a%b);
}
long long exgcd(long long a,long long b,long long &x,long long &y)
{
    if(b==0)
    {
        x=1;
        y=0;
        return a;
    }
    else
    {
        long long ans=exgcd(b,a%b,x,y);
        long long t=x;
        x=y;
        y=t-a/b*y;
        return ans;
    }
}
int main()
{
    long long n,c1,c2,n1,n2;
    while(scanf("%lld",&n),n)
    {
        scanf("%lld%lld",&c1,&n1);
        scanf("%lld%lld",&c2,&n2);
        long long x,y;
        long long tmp=gcd(n1,n2);
        if(n%tmp!=0)
        {
            printf("failed
");
        }
        else
        {
            n/=tmp;
            n1/=tmp;
            n2/=tmp;
            exgcd(n1,n2,x,y);
            if(n1*c2<n2*c1)
            {
                x*=n;
                x%=n2;
                y=(n-x*n1)/n2;
            }
            else if(n1*c2==n2*c1)
            {
                if(n1<=n2)
                {
                    x*=n;
                    x%=n2;
                    y=(n-x*n1)/n2;
                }
                else
                {
                    y*=n;
                    y%=n1;
                    x=(n-y*n2)/n1;
                }
            }
            else
            {
                y*=n;
                y%=n1;
                x=(n-y*n2)/n1;
            }
            int tag=0;
            if(x<0)
            {
                while(x<0)
                    x+=n2;
                y=(n-x*n1)/n2;
                if(y<0)
                    tag=-1;
            }
            else if(y<0)
            {
                while(y<0)
                    y+=n1;
                x=(n-y*n2)/n1;
                if(x<0)
                    tag=-1;
            }
            if(tag==-1)
                printf("failed
");
            else
                printf("%lld %lld
",x,y);
        }
    }
    return 0;
}
AC Code
原文地址:https://www.cnblogs.com/overflow/p/3149010.html