赞
踩
题目大意:假设给定一序列 a a a,对于序列中的 a i a_i ai,如果 a i a_i ai是素数,那么找到第 a i a_i ai个素数加入序列 a a a的尾部,如果 a i a_i ai是合数,那么将其最大的非 a i a_i ai的因子加入序列 a a a的尾部.现在给定一个长度为 2 n 2n 2n由长度为 n n n的序列 a a a生成的序列 b b b(无序).求出原序列 a a a.
解题思路:首先对于当前最大的素数,它一定由它次大的素数生成,对于当前最大的合数,它一定是原本存在于序列之中的,当前序列中存在它的最大因此,通过贪心规则确立了基本的构造原理之后,直接模拟即可.
#include<bits/stdc++.h> using namespace std; #define ll long long #define syncfalse ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); const int MAX = 1e6 + 5; const int N = 5e5 + 5; int a[N]; bool notPrime[50000005]; int Prime[MAX]; int cnt = 0; int n; inline void solve(int n) { for (int i = 2; i <= n; ++i) { if (!notPrime[i]) { Prime[++cnt] = i; } for (int j = 1; j <= cnt && Prime[j] * i <= n; ++j) { notPrime[Prime[j] * i] = true; if (i % Prime[j] == 0)break; } } } int num[N]; int main() { syncfalse #ifndef ONLINE_JUDGE freopen("in.txt", "r", stdin); #endif solve(3000000); int n; cin >> n; n *= 2; vector<int>ans; for (int i = 1; i <= n; ++i) { cin >> a[i]; num[a[i]]++; } sort(a + 1, a + 1 + n); for (int i = n; i >= 1; --i) { if (num[a[i]] == 0)continue; num[a[i]]--; if (notPrime[a[i]]) { for (int j = 1; j <= cnt; ++j) { if (a[i] % Prime[j] == 0) { ll tem = a[i] / Prime[j]; num[tem]--; ans.push_back(a[i]); break; } } } else { ll index = lower_bound(Prime + 1, Prime + 1 + cnt, a[i]) - Prime; num[index]--; ans.push_back(index); } } for (auto x : ans)cout << x << " "; return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。