可以无限制的两两做差,这让人想到了一个东西:辗转相减法求最大公约数
假设这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;
}
通过两两相减求解最大公约数的方法,利用exgcd算法,找到一组bi和bj使得gcd(bi, bj)=1,然后通过辗转相减得到最大公约数g。最后,根据最大数减去g的倍数,确定可能的解。"
88949840,8197226,K-Means聚类算法详解与优化,"['机器学习', '数据挖掘', '无监督学习', '聚类', 'K-Means算法']
1037

被折叠的 条评论
为什么被折叠?



