AtCoder Grand Contest 018A: Getting Difference 题解

通过两两相减求解最大公约数的方法,利用exgcd算法,找到一组bi和bj使得gcd(bi, bj)=1,然后通过辗转相减得到最大公约数g。最后,根据最大数减去g的倍数,确定可能的解。" 88949840,8197226,K-Means聚类算法详解与优化,"['机器学习', '数据挖掘', '无监督学习', '聚类', 'K-Means算法']

可以无限制的两两做差,这让人想到了一个东西:辗转相减法求最大公约数

假设这n个数的最大公约数是g,那么ai可以表示为bi*g,所以任意两两相减得到的所有结果都是g的倍数

这所有的bi中一定存在一组bi和bj,满足gcd(bi,bj)=1,否则g就不是最大公约数了

那么由exgcd得,ax+by=gcd(a,b)有整数解,所以盯着这组gcd=1的bi,bj做辗转相减,一定可以得到g

有了g,那么拿着所有数中的最大数不停地减g,就可以得到小于等于max的所有g的倍数

总之,这些数任意两两相减所得结果的集合,就是不大于max的所有的g的倍数

只要k<=max且k%g=0,就是possible,否则是impossible

#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <cmath>
#include <algorithm>
#include <cstdlib>
#include <utility>
#include <map>
#include <stack>
#include <set>
#include <vector>
#include <queue>
#include <deque>
#define x first
#define y second
#define mp make_pair
#define pb push_back
#define LL long long
#define Pair pair<int,int>
#define LOWBIT(x) x & (-x)
using namespace std;
 
const int MOD=1e9+7;
const int INF=1e9;
const int magic=348;
 
int n,k;
int a[100048];
 
int gcd(int x,int y)
{
	return y==0?x:gcd(y,x%y);
}
 
int main ()
{
	int i;
	scanf("%d%d",&n,&k);
	int maxn=-1;
	for (i=1;i<=n;i++) 
	{
		scanf("%d",&a[i]);
		maxn=max(maxn,a[i]);
	}
	if (k>maxn)
	{
		printf("IMPOSSIBLE\n");
		return 0;
	}
	int g=a[1];
	for (i=2;i<=n;i++) g=gcd(g,a[i]);
	if (k%g==0) printf("POSSIBLE\n"); else printf("IMPOSSIBLE\n");
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值