牛客练习赛60 D-斩杀线计算大师

题目描述
算术能力是每个炉石玩家必不可少的,假设现在有三种伤害卡,伤害值分别是a,b,ca,b,ca,b,c。并且每种伤害卡的数量你可以认为是无限的。现在牛牛想知道是否存在一种方式可以刚好造成kkk点伤害,输出x,y,zx,y,zx,y,z分别表示三种伤害卡的使用个数。
数据保证一定存在解。如果存在多组解,输出任意一组。

输入描述:

一行四个整数分别表示a, b, c, k.

输出描述:

一行输出三个整数分别表示x,y,z.

示例1

输入:3 4 5 20

输出:4 2 0

备注:

1≤a,b,c≤1e5
1e120≤k≤1e12

稍微说一下:通过遍历其中一个系数,然后用扩展欧几里得算法得到另外两个就行了,需要注意的是这题系数都要是正整数,所以需要变形一下,方法和过程都在代码里,所以

直接上代码,O(∩_∩)O哈哈~:

#include<cstdio>
using namespace std;
typedef long long LL;
LL exgcd(LL a, LL b, LL &x, LL &y){//扩展欧几里得算法 
	if (b == 0){
		x = 1, y = 0;
		return a;
	}
	LL ans = exgcd(b,a%b,x,y);
	/******************************
	x[i] = y[i+1]         
	y[i] = x[i+1] - K[i] * y[i+1]
	******************************/
	LL tmp = x;
	x = y;
	y = tmp - (a / b) * y;
	return ans;
}
LL get(LL a, LL b, LL c) {//返回一组解 
	LL X, Y, gcd = exgcd(a, b, X, Y);
	if (c % gcd) return -1;//c不是gcd的倍数->无解 
	if (b == 0) return c / gcd * X;//b为零的特殊情况 
	/******************************
	设 x,y,K=c/gcd 其中x大于零 且 xa + yb = c; 
	所以 XK = (x + A), YK = (y - B); 
	Xa + Yb = gcd; ==> (x + A)a + (y - B)b = c;
	Aa - Bb = 0; ==> A = kb, B = ka;
	可得 x = XK - kb; ==>  x = (XK % b + b) % b;
	*******************************/
	return (c / gcd * X % b + b) % b; //x为符合要求的最小正整数 
}
int main(){
	LL a, b, c, n;
	scanf("%lld%lld%lld%lld", &a, &b, &c, &n);
	for(LL i = 0; i * c <= n; ++i) {//对c进行遍历 
		LL k = n - i * c;
		LL res = get(a, b, k); 
		if (res != -1) {
			LL ans =  b ? (k - a * res) / b : 0;
			printf("%lld %lld %lld\n", res, ans, i);
			break;
		}
		if (c == 0) {//c为零的特殊情况 
			break;
		}
	}
	return 0;
} 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值