版权声明:本文为博主原创文章,转载请注明博客地址: 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;
}