UVA - 10090

这题和上次卢总讲的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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值