题目链接:https://vjudge.net/problem/CodeForces-1198F
转自:https://www.cnblogs.com/realSpongeBob/p/11416754.html
题意:有一串数字序列,问能否分成两组,使得每组的最大公约数为1,每组最少1个数。
思路:用到了随机数,先把序列随机打乱,遍历当前数,如果当前数使得第一组的gcd变小,就加进去,否则加到第二组。
随机数:头文件 ctime,srand是随机数种子,每一个种子对应不同的一组随机数,用time(0)初始化,即srand(time(0)).初始化一次就好,然后用rand()返回一个随机数。可以用取余来限制。
此题用到的随机数知识点转自:https://www.cnblogs.com/shiney/archive/2011/06/30/2095118.html
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
int n,a[maxn],id[maxn],ans[maxn];
inline int gcd(int a,int b)
{
return b?gcd(b,a%b):a;
}
int main()
{
scanf("%d",&n);
for(int i=1; i<=n; i++)
{
scanf("%d",&a[i]);
id[i]=i;
}
clock_t st=clock();//获取开始时间
while(clock()-st<0.45*CLOCKS_PER_SEC)//因为题目要求500ms 因此每次检查当前
{ //已经运行的时间 规定不超过450ms*一秒内的计时单元
random_shuffle(id+1,id+n+1);//随机排序
int x=0,y=0;
for(int i=1; i<=n; i++)
{
int t=gcd(x,a[id[i]]);
if(t==x)//gcd没有减小 只能放到第二组
{
y=gcd(y,a[id[i]]);
ans[id[i]]=2;
}
else//gcd减小了 可以放到第一组
{
x=t;
ans[id[i]]=1;
}
}
if(x==1&&y==1)//两组gcd都是1
{
puts("YES");
for(int i=1; i<=n; i++)
{
if(i!=1)
printf(" ");
printf("%d",ans[i]);
}
return 0;
}
}
puts("NO");
return 0;
}