Codeforces 582 A. GCD Table

Codeforces Tutorial

A. GCD Table

Problem Analysis

对于\(G_{n\times n}\)中的每个元素\({g_i}_j\)有:

\[{g_i}_j=gcd(a_i,a_j) \]

要求构造数组\(a_{1 \times n}\)

假设已经构造出 \(a_1,a_2,\cdots,a_n\),顺序不影响结果,不妨设\(a_i \le a_j\),如果\(i \lt j\)

\(gcd(a_n, a_n) = a_n ≥ a_i ≥ gcd(a_i, a_j)\)for every \(1 ≤ i, j ≤ n.\)

所以可以

  1. 每一次取出最大的元素\(a_k\)
  2. 然后删除 对于\(k \lt i \le n\),删除\(gcd(a_k,a_k),gcd(a_i,a_k),gcd(a_k,a_i)\)

Acepted Code

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<string>
#include<vector>
#include<cmath>
#include<map>
#include<istream>
#include<cassert>
#include<set>
#include<functional>
#define DEBUG(x) cout<<#x<<" = "<<x<<endl
#define DEBUG2(x,y) cout<<#x<<" = "<<x<<" , "\
<<#y<<" = "<<y<<endl
using namespace std;
typedef long long ll;
int _gcd(int a,int b)
{
    if(b==0)return a;
    return _gcd(b,a%b);
}
int gcd(int a,int b)
{
    if(a<b)swap(a,b);
    return _gcd(a,b);
}
map<int,int>cnt;
multiset<int,greater<int> >tbl;
int main()
{
//    freopen("in.txt","r",stdin);
    int n;
    scanf("%d",&n);
    for(int ii=0;ii<n*n ;ii++ ){
        int t;
        scanf("%d",&t);
        cnt[t]++;
        tbl.insert(t);
    }
    vector<int>ans;
    for(auto ii:tbl){
        if(cnt[ii]==0)continue;
        for(int jj=0;jj<ans.size();jj++){
            cnt[gcd(ans[jj],ii)]-=2;
        }
        cnt[ii]--;
        ans.push_back(ii);
    }
    for(auto a:ans){
        printf("%d ",a);
    }
}

Wrong Answer Cases

Test 1

思路错误

What I Learn

构造最后结果的状态,根据最终状态推导出求解的过程

Reference

http://codeforces.com/blog/entry/20692

posted @ 2019-06-15 15:41  MalcolmMeng  阅读(247)  评论(0编辑  收藏  举报