标签:
有一个序列,给出该序列中的数两两的gcd,并打乱顺序,求原序列。
首先,原序列中的数一定会在新序列中出现,而且gcd(a, b) <= a, b。那么新序列中最大和次大的数一定是原序列中的数,那第三大是不是呢?显然要先去除已经确定的数的两两gcd,再找剩下的数最大数。
写完才发现写得有点蠢。
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <map> 5 using namespace std; 6 7 const int N = 1e3 + 10; 8 int n, a[N * N], sum[N * N], ans[N], cnt; 9 10 map <int, int> mp; 11 12 int gcd(int x, int y) { 13 return y ? gcd(y, x % y) : x; 14 } 15 16 bool cmp(int x, int y) {return x > y;} 17 18 void work() { 19 int k = 3; 20 ans[1] = a[1], ans[2] = a[2]; 21 sum[mp[a[1]]] --, sum[mp[a[2]]] --; 22 for (int i = 2; i < n; i ++) { 23 for (int j = 1; j < i; j ++) sum[mp[gcd(ans[i], ans[j])]] -= 2; 24 while (!sum[mp[a[k]]]) k ++; 25 ans[i + 1] = a[k]; 26 sum[mp[a[k]]] --; 27 } 28 } 29 30 int main() { 31 scanf("%d", &n); 32 for (int i = 1; i <= n * n; i ++) { 33 scanf("%d", &a[i]); 34 if (mp.find(a[i]) == mp.end()) mp[a[i]] = ++cnt; 35 sum[mp[a[i]]] ++; 36 } 37 sort(a + 1, a + n * n + 1, cmp); 38 work(); 39 for (int i = 1; i <= n; i ++) printf("%d ", ans[i]); 40 return 0; 41 }
标签:
原文地址:http://www.cnblogs.com/awner/p/5778183.html