Legendary Weights | ||||||
| ||||||
Description | ||||||
Long long ago, there were n kind of weights. Each kind of weights is in infinite quantity. With a balance and these weights, can you determine an arbitrary object’s weight? (The weight is always an integer.) The balance can only determine which side is heavier or equal. | ||||||
Input | ||||||
There are multiple test cases. The first line contains an integer n(1 ≤ n ≤ 104), which is the number of different kinds of weights. The second line contains n integers, separated by a space. The i-th integer ai (1 ≤ a i ≤ 109 ) represents the weight of the i-th weight. | ||||||
Output | ||||||
Print “YES” in a line if possible, “NO” if otherwise. | ||||||
Sample Input | ||||||
1 1 2 2 3 | ||||||
Sample Output | ||||||
YES YES | ||||||
Source | ||||||
“尚学堂杯”2015级程序设计竞赛(11月)正式赛 |
题目大意:
一共给你N种砝码的重量,并且每种砝码的个数我们设定为无限,判断我们是否能够通过这N种砝码来称量出任意重量的物品。
思路:
1、本题和大富翁双六问题很相似(挑战程序竞赛第二版啊):
②给你一个色子,上边一共有四个数字:a,b,-a,-b,起点位于0处,问我们能否通过扔色子走到位子1处。
那么我们不难理解,如果Gcd(a,b)!=1,那么是一定永远不可能走到位子1的,反之,如果Gcd(a,b)==1,那么是一定有方案可以走到位子1的
2、那么我们根据上述情况探究本题的做法:
①对应因为砝码的个数我们设定为无限,那么我们考虑,就是相当于找一个方案,使得分配砝码在天平的左右两侧(一边就是正值,一边就是负值)那么如果一共有两种砝码,那么此时问题就和上述双六问题是一毛一样的。其实就是相当于,如果我们找到了一种放置方案,使得这两种重量的砝码找到了能够称量出重量为1或者是重量为2的物品的方案,那么对应我们就一定可以通过倍数递增的方案,来称量出任意重量的物品了。那么我们求出这两个数的Gcd,如果Gcd==1或者Gcd==2,都是可行方案,其余的都不行。
(重量为2的情况:任意数都可以用二进制数来表示,且重量为1的情况我们特殊判定就能测定出任意重量的物品了,如果gcd==3,很明显物品重量为1和重量为2都测不出来,没法界定这两个重量的物品对应的重量,再之后不再列举,所以只能为Gcd==1或者是Gcd==2);
②那么当前问题是N种重量的砝码,那么我们只要将所有数字都Gcd起来,看最终的Gcd是否为1或者2即可。
Ac代码:
#include<stdio.h>
#include<string.h>
using namespace std;
int gcd(int x,int y)
{
if(x%y==0)return y;
else return gcd(y,x%y);
}
int a[100500];
int main()
{
int n;
while(~scanf("%d",&n))
{
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
int g=a[0];
for(int i=1;i<n;i++)
{
g=gcd(a[i],g);
}
if(g==2||g==1)
{
printf("YES\n");
}
else printf("NO\n");
}
}