题目
给定几种重量的砝码,数量不限,判断是否可以称出任意重量的物品。
输入规则,第一行输入一个整数n,表示有n种砝码;然后挨个输入每个砝码的重量。可以称重的物品都是整数。能,就输出YES;不能,输出NO。
示例1
输入:1
1输出:
YES
第一个1是有一种重量的砝码,第二个1是这个砝码是多重。这样肯定可以称出任意重量的物品。
示例2
输入:2
2 3输出:
YES
第一个2是有两种重量的砝码,第二行2 3表示每种砝码重量是2和3,那么也是可以称出任意重量的物品。
示例3
输入:2
2 4输出:
NO
这一组只能得到2N物品的重量,无法称出奇数物品的重量。
思路:
如果给定砝码种包含重量为1的砝码,显然一定可以称出任意重量,如果若干个砝码经过换算能得到重量 1 ,则也可以称出任意重量的砝码。
比如3,5,2x3-5=1,显然我们可以通过3,5两个砝码称出任意的重量(例如,将2个3kg的砝码看作为一组,称为A;一个5kg的砝码看作一组,称其为B; 一个A放在天平左边,一个B放在右边,则可以称出质量为1kg的货物;2个A放在天平左边,2个B放在右边,则可以称出质量为2kg的货物,...............)
(之前,我的思路的局限: 只要有两种砝码的质量差为1就可以,忽视了多个砝码的组合运算!!!)
那么满足什么条件的砝码可以得到重量1呢?
设砝码的质量为a1,a2,...,an, 相应的个数为x1,x2,...,xn, 当 a1*x1+a2*x2+…+an*xn = 1 有整数解的时候,则这组砝码可以称出任意质量的物体;
网友说需要用到数学定理:
如果a1,a2,…,an是正整数,当且仅当 d =(a1,a2,……,an)能整除c的时候,方程a1*x1+a2*x2+…+an*xn=c有整数解,另外当存在一个解的时候,那么方程有无穷多个解。
-->(a1,a2,……,an)的最大公约数为1时有解。
我们需要解决的问题,等价于n元一次方程a1x1+a2x2+…+an*xn=1是否有解。也就是求给定的n种砝码重量的最大公约数是否为1.
即:当a1,a2,a3,a4,…an 这n个正整数的最大公约数是1时,他们可以表示任意的重量。
(显而易见: 如果两个数的最大公约数是1 ,那么包含这两个数正整数序列的最大公约数也一定是1)。
可以使用辗转相除法求两个数的最大公约数。
#include<iostream>
using namespace std;
int main()
{
int n;
while (cin >> n)
{
int imax, imin;
int num = 0;
cin >> num;
imin = num;//先让imin等于第一个数
if (num == 1)
{
cout << "YES" << endl;
break;
}
for(int i=1;i<n;++i)
{
cin >> num;
if (num == 1)
{
cout << "YES" << endl;
return 0;
}
imax = num;
if (imax < imin)//imax总是大于imin
swap(imax,imin);
while (imin != 0)//辗转相除求最大公约数
{
int rest = imax % imin;
imax = imin;
imin = rest;
}
if (imax == 1)//余数为1时返回
{
cout << "YES" << endl;
return 0;
}
imin = imax;//imin等于前两个数的最大公约数
}
cout << "NO" << endl;
return 0;
}
return 0;
}
Ref:
https://blog.csdn.net/weixin_43327696/article/details/105956767