Codeforces-959D Mahmoud and Ehab and another array construction task(貪心)
阿新 • • 發佈:2019-02-12
題意:
給定陣列a,求大於或者等於陣列a字典序的陣列b,滿足任意i,j,gcd(bi, bj) = 1。並且是在所有滿足條件中的字典序最小的一個。
思路:
任意一對數互質,可以通過標記其質因子來解決,在找到第一個違背互質的數時,只需要找出大於該數的最小的一個與前面所有數互質的數,在此之後,要想保證字典序最小,便是所有可用的質數從小向大取。
程式碼:
#include <bits/stdc++.h> using namespace std; const int N = 3e6; const int maxn = 1e5+5; int prime[N+5], cnt; bool isprime[N+5]; void prime_init() { for(int i = 2; i <= sqrt(N); ++i) { if(!isprime[i]) { for(int j = i*i; j <= N; j+=i) { isprime[j] = 1; } } } cnt = 0; for(int i = 2; i <= N; ++i) { if(!isprime[i]) { prime[++cnt] = i; } } // printf("%d\n", cnt); } int n, a[(int)1e5+5]; bool vis[N+5]; bool jg(int x, int flag) { for(int i = 1; i <= cnt && prime[i]*prime[i] <= x; ++i) { if(x % prime[i] == 0) { if(vis[prime[i]]) { return false; } if(flag) { vis[prime[i]] = 1; } while(x % prime[i] == 0) { x /= prime[i]; } } } if(x > 1) { if(vis[x]) { return false; } if(flag) { vis[x] = 1; } } return true; } bool work(int id) { if(jg(a[id], 0)) { jg(a[id], 1); return false; } for(int i = a[id]+1; ; ++i) { if(jg(i, 0)) { jg(i, 1); a[id] = i; break; } } return true; } int main() { prime_init(); scanf("%d", &n); int flag = 0, no = 1; for(int i = 1; i <= n; ++i) { scanf("%d", &a[i]); if(flag) { while(vis[prime[no]]) { ++no; } a[i] = prime[no++]; continue; } if(work(i)) { flag = 1; } } for(int i = 1; i <= n; ++i) { printf("%d%c", a[i], i==n?'\n':' '); } return 0; }
繼續加油~