Codeforces 582 A. GCD Table

Codeforces Tutorial

A. GCD Table

Problem Analysis

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

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

要求构造数组(a_{1 imes 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

原文地址:https://www.cnblogs.com/MalcolmMeng/p/11027797.html