D:GCD
- 集合 S 包含 1 至 n 所有的数
- 从集合S中找任意找子集T(T中包含k个数),都存在(存在任意两个数x,y),满足gcd(x,y) > 1
- 求最小k
题目分析:
- 最小k:最坏情况选择k个数满足条件
- 素数满足两两互质、1与任何数都互质,gcd(a,b) = 1不满足gcd(x,y)>1,都要加上
- 素数和1选择完毕,需要加上一个合数,这样就满足条件
- 最小k:把(1~n)中所有素数筛选出来,加上1和一个合数
- k不存在的情况是:k > n,没有k个数可以选
代码如下:
#include<bits/stdc++.h>
using namespace std;
#define mm(a,x) memset(a,x,sizeof a)
#define mk make_pair
#define ll long long
#define pii pair<int,int>
#define inf 0x3f3f3f3f
#define lowbit(x) (x) & (-x)
const int N = 1e5 + 10;
int primes[N],cnt;
int st[N];
int n;
void get_primes(){
mm(st,0);
for(int i = 2; i <= n; i ++ ){
if(!st[i]) st[i] = i,primes[++ cnt] = i;
for(int j = 1; j <= cnt; j ++ ){
if(primes[j] > st[i] || primes[j] > n/i) continue;
st[i * primes[j]] = primes[j];
}
}
}
int main() {
cin >> n;
get_primes();
int ans = cnt + 2;
if(ans > n) cout<<-1;
else cout<<ans;
return 0;
}