2219. A famous math puzzle

来源:互联网 发布:windows游戏模拟器 编辑:程序博客网 时间:2024/05/18 09:07
¡题目描述:
有n个壶,和无穷多的水.每次我们只能:
1.把其中一个壶灌满.
2.把其中一个壶倒空.
3.把一个壶中的水倒入另一个壶中,直到一个壶为空或者另一个壶已经满了为止.
给定一个体积W,问能否经过若干次倒水后使得最终有一个壶中只剩下W升水?如果能,输出”YES”,否则输出”NO”

要使n个水壶能倒出w体积的水,则必须符合以下两个条件:
1.至少有一个水壶的容量大于或等于w.
2.假设p是n个水壶容量的最大公约数,那么w必须p的倍数.

为什么是最大公约数的倍数的解释(刚开始真的不懂,后来明白了):
假设n个水壶的容量分别为C1,C2,C3…..Cn.
必要性:不管执行三种操作的那一种,壶中所含的水一定是P的整数倍.
充分性:由欧几里德算法扩展可知,必然存在整数A1,A2,A3…..An,使得

A1*C1+A2*C2+A3*C3+…+An*Cn=W.

  如果Ai是正数,我们就用第i个壶从水源中取Ai次水;如果Ai为负数,我们就把第i个壶倒空Ai次,这样最后必会剩下W升水




Maybe you knew this famous puzzle when you were a child.

You have two jugs, A and B, and an infinite supply of water. There are three types of actions that you can use: (1) you can fill a jug, (2) you can empty a jug, and (3) you can pour from one jug to the other. Pouring from one jug to the other stops when the first jug is empty or the second jug is full, whichever comes first.

For example, if A has 5 gallons and B has 6 gallons and a capacity of 8, then pouring from A to B leaves B full and 3 gallons in A. As to a given cubage W, a solution is a sequence of steps that leaves exactly W gallons in one of the jugs.

For example, when A=5, B=6 and W=4, we can take the following steps to achieve the goal.

 ABinitial00fill A50pour A B05fill A55pour A B46empty B40

Today, we will generalize the puzzle. You are given N jugs, and asked to decide whether a goal W can be achieved.

Input

Input to your program consists of multiple test cases. Every test case starts with a line consists of two integers N and W. Then N lines follow, each line consisits of a single positive integer that is the capacity of the ith jug (1 ≤ N ≤ 100).

Input is terminated with N=0 and W=0.

Output

For each test case, if the goal can be achieved, you should output YES in a single line. Otherwise output NO in a single line.

Sample Input

2 4562 1065392 12483 91035140 0

Sample Output

YESNONOYES

#include<iostream>#include<cstring>using namespace std;int gcd(int a,int b){if(b==0)return a;elsereturn gcd(b,a%b);}int main(){int n,w,a[100];while(cin>>n>>w&&n){int max=0;for(int i=0;i<n;i++){cin>>a[i];if(a[i]>max)max=a[i];}if(max<w){cout<<"NO"<<endl;continue;}if(n==1){if(a[0]==w)cout<<"YES"<<endl;elsecout<<"NO"<<endl;continue;}else{int temp=gcd(a[n-1],a[n-2]);for(int i=n-3;i>=0;i--){temp=gcd(temp,a[i]);}if(w%temp==0)cout<<"YES"<<endl;elsecout<<"NO"<<endl;}}return 0;}


0 0
原创粉丝点击