atcoder grand Contest 018 A - Getting Difference

Time limit : 2sec / Memory limit : 256MB

Score : 300 points

Problem Statement

There is a box containing N balls. The i-th ball has the integer Ai written on it. Snuke can perform the following operation any number of times:

  • Take out two balls from the box. Then, return them to the box along with a new ball, on which the absolute difference of the integers written on the two balls is written.

Determine whether it is possible for Snuke to reach the state where the box contains a ball on which the integer K is written.

Constraints

  • 1N105
  • 1Ai109
  • 1K109
  • All input values are integers.

Input

Input is given from Standard Input in the following format:

N K
A1 A2  AN

Output

If it is possible for Snuke to reach the state where the box contains a ball on which the integer K is written, print POSSIBLE; if it is not possible, print IMPOSSIBLE.


Sample Input 1

3 7
9 3 4

Sample Output 1

POSSIBLE

First, take out the two balls 9 and 4, and return them back along with a new ball, abs(94)=5. Next, take out 3 and 5, and return them back along withabs(35)=2. Finally, take out 9 and 2, and return them back along with abs(92)=7. Now we have 7 in the box, and the answer is therefore POSSIBLE.


Sample Input 2

3 5
6 9 3

Sample Output 2

IMPOSSIBLE

No matter what we do, it is not possible to have 5 in the box. The answer is therefore IMPOSSIBLE.


Sample Input 3

4 11
11 3 7 15

Sample Output 3

POSSIBLE

The box already contains 11 before we do anything. The answer is therefore POSSIBLE.


Sample Input 4

5 12
10 2 8 6 4

Sample Output 4

IMPOSSIBLE
题目:给一个N,一个K,再给一串长度为N的序列,在保持原先元素不变的情况下还可以一直往里面加各个元素差值的元素,直到无法再加入新的元素为止,问就这样一直加元素,看看可不可能在序列里找到目标元素,如果可能,输出POSSIBLE,否则输出IMPOSSIBLE.
思路:用暴力求也可以,我本来是用暴力求的,但是这样子太傻了,仔细分析一下数字的规律,从最简单的情况开始分析起来,如果一个数字是一,那么小于等于这串序列里面最大值的数字都是可以得到的,因为那个最大值可以通过一直减一来得到小于等于它的值,既全覆盖。
然后,如果一个序列里有两个数字,并且它们互质(既最大公约数是1)那么他们是可以一直减来减去减出一个1来,因为通过辗转相除法可以知道,辗转相除法的原理是,如果a%b!=0,设c=a%b;a=b;b=c;其实就是把b给a,然后把b的值变成a对b取膜的值,而a对b取膜就是一直让a-b直到a小于b,所以c是可以通过a-b得到的,同理,我们就可以重复执行这个操作直到得出最大公约数,所以这就是为什么如果一个序列里有两个数字,并且它们互质(既最大公约数是1)那么他们是可以一直减来减去减出一个1来。
然后,考虑一般情况,假设一串数字,我们找到它们的最大公约数,把它们变成最大公约数乘以另一个数字的形式,我们先把所有数字除去最大公约数,剩下来的一串序列必定是互质的,比如说最大公约数是2,有一串序列为 2*5 , 2*8, 2*9  , 2*7,2*88。我们作减运算的时候其实是把最大公约数提取出来,把右边的因子作减法的,比如2*88-2*5=2*(88-5)。然后我们可以发现,如果我们提取出了最大公约数,那么剩下来的数字序列必定是互质的,既然是互质的,那么必定可以减出一个1;那么我们就必定可以得到小于除以最大公约数后的序列的最大值的所有值,那么我们再乘以最大公约数,那么我们就可以得到小于序列里的又是最大公约数的倍数的所有数字,不管怎么减最终情况都是这样,既然这样那么我们就可以看目标数字了,如果目标数字是最大公约数的倍数并且小于等于序列里的最大值,那么我们就必定可以得到,否则就不可能,至此这道题就完美解决了。
下面附上我的213代码和大牛的666代码:
#include<set>
#include<map>
#include<stdio.h>	
using namespace std;
set<int>Se;
map<int,int>mmp;
int main()
{
	int N,K;
	int max=-1,min=100001;
	scanf("%d%d",&N,&K);
	while(N--)
	{
		int num;
		scanf("%d",&num);
		max=num>max ? num : max;
		min=num<min ? num : min;
		Se.insert(num);	
		mmp[num]++;
	}
	set<int> :: iterator it=Se.begin(); 
	if(K>max)
		printf("IMPOSSIBLE");
	else
	{
		int Size=Se.size();
		while(1)
		{
			if(mmp[K]!=0)
				break;
			set<int> :: iterator it=Se.begin(); 
			int n=*it;
			for(it++;it!=Se.end();it++)
			{
				int value=(*it)-n;
				min= min < value ? min :value;
				mmp[value]++;
				if(K%min == value %min)
				{
					mmp[K]++;
					break;
				}
				Se.insert((*it)-n);
				n=*it;
			}
			if(Size==Se.size())
				break;
			Size=Se.size();
		}
		if(mmp[K]!=0)
			printf("POSSIBLE");
		else
			printf("IMPOSSIBLE");
		printf("\n");
	}
	return 0;
}


 
  
 
  
#include <bits/stdc++.h>
using namespace std;
 
int n, k, mx, g;
 
int main(){
	scanf("%d%d", &n, &k);
	for(int x; n--; ){
		scanf("%d", &x);
		mx = max(mx, x);
		g = __gcd(g, x);
	}
	if(k > mx || k % g) printf("IM");
	puts("POSSIBLE");
}

虽然不知道这位大牛是谁,但是感谢大牛的代码。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值