这题和上次卢总讲的big-small思想的题不一样,必须装满背包,否则输出failed
一直在尝试用之前那题的思想做,忘记exgcd了= =(其实好久没写了想到也写不出)
复习一下exgcd,ax+by=bx2+(a%b)y2=gcd(a,b),到最下面时b=0了,那么ax=gcd(a,b)=a,x=1,y=0
然后要得到ax+by=c的话,还要x*=c/gcd,y*=c/gcd.
关于多解的话,a(x-b/gcd)+b(y+a/gcd)=c,因为a*b/gcd就是ab的最小公倍数,每次x,y的变换使得ax2和by2的大小差距都必须是ab的最小公倍数才行。
于是这题就选择性价高的尽量多就行蛤。
注意有可能最后x,y还是有小于0的情况比如说n小于n1或n2的情况,所以要再判断一次failed
#include<cstdio>
#include<cstring>
long long n,c1,n1,c2,n2,a,b,c,x,y;
long long exgcd(long long a,long long b)
{
if(b==0)
{
x=1;y=0;
return a;
}
long long gcd=exgcd(b,a%b),t=x;
x=y;y=t-(a/b)*y;
return gcd;
}
int main()
{
while(~scanf("%lld",&n))
{
if(n==0)
return 0;
scanf("%lld%lld%lld%lld",&c1,&n1,&c2,&n2);
a=n1;b=n2;
long long gcd=exgcd(a,b);
if(n%gcd!=0)
printf("failed\n");
else
{
x=x*(n/gcd);y=y*(n/gcd);
if(c1*n2<=c2*n1)
{
y=y%(a/gcd);
if(y<0)
y+=a/gcd;
x=(n-y*b)/a;
}
else
{
x=x%(b/gcd);
if(x<0)
x+=b/gcd;
y=(n-x*a)/b;
}
if(x<0 || y<0)
printf("failed\n");
else
printf("%lld %lld\n",x,y);
}
}
return 0;
}