小易买苹果

版权声明:本文为博主原创文章,转载请注明博客地址: https://blog.csdn.net/zy010101/article/details/88379415

题目描述

小易去附近的商店买苹果,奸诈的商贩使用了捆绑交易,只提供6个每袋和8个每袋的包装(包装不可拆分)。 可是小易现在只想购买恰好n个苹果,小易想购买尽量少的袋数方便携带。如果不能购买恰好n个苹果,小易将不会购买。

解法

这个题目很容易就可以写出下面的式子:6x+8y=n;非常直观的解法就是求解这个线性丢番图方程。这个方程的求解可以使用扩展欧几里得算法。我们求出其x的一个最小非负整数值,然后求出y的值。

在求解之前,我们先来看看这个方程的通解形式,这是必要的。

设整数a,b,c;若方程ax+by = c的一组整数解为(x0,y0);那么它的任意组整数解都可以写成:(x0+kb',y0-ka').

其中a' = a / gcd(a,b);b' = b / gcd(a,b);k取整数即可。有了这个,我们就开始写。

#include<iostream>
using namespace std;

int exgcd(int a,int b, int &x,int &y);
int sol(int a,int b,int c,int &x,int &y);

int main()
{
	int a = 6;
	int b = 8;
	int c;
	int x, y;
	cin >> c;
	int tmp = sol(a, b, c, x, y);
	y = (c - a * tmp) / b;
	if (-1 == tmp || y < 0)		//保证y >= 0
	{
		cout << -1;
	}
	else
	{
		cout << tmp + y;
	}
	system("pause");
	return 0;
}

int exgcd(int a, int b, int & x, int & y)
{
	if (0 == b)
	{
		x = 1;
		y = 0;
		return a;
	}
	int gcd = exgcd(b, a % b, x, y);
	int temp = x;
	x = y;
	y = temp - a / b * y;
	return gcd;
}

int sol(int a,int b,int c, int &x, int &y)
{
	int gcd = exgcd(a, b, x, y);
	if (0 != c % gcd)
	{
		return -1;		//无法刚好买n个苹果
	}
	x *= c / gcd;		//将x化为6x+8y=n的解
	b /= gcd;
	if (b < 0)
	{
		b = -b;
	}
	int r = x % b;
	if (r < 0)
	{
		r += b;
	}
	return r;
}

 

猜你喜欢

转载自blog.csdn.net/zy010101/article/details/88379415
今日推荐