2219. A famous math puzzle

¡題目描述:
有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.

  A B
initial 0 0
fill A 5 0
pour A B 0 5
fill A 5 5
pour A B 4 6
empty B 4 0

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 4
5
6
2 10
65
39
2 12
4
8
3 9
10
35
14
0 0

Sample Output

YES
NO
NO
YES

#include<iostream>
#include<cstring>
using namespace std;
int gcd(int a,int b)
{
	if(b==0)
		return a;
	else
		return 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;
			else
				cout<<"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;
			else
				cout<<"NO"<<endl;
		}
	}
	return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章