码迷,mamicode.com
首页 > 其他好文 > 详细

CODEFORCES #523 C. GCD Table

时间:2016-08-16 23:40:10      阅读:152      评论:0      收藏:0      [点我收藏+]

标签:

题目描述:

有一个序列,给出该序列中的数两两的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 }

 

CODEFORCES #523 C. GCD Table

标签:

原文地址:http://www.cnblogs.com/awner/p/5778183.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!