zoukankan      html  css  js  c++  java
  • CodeForces

    题意:给你n*n gcd表中的所有数(以任意顺序) ,求对角线上的n个数分别是什么。gcd表定义如下,先将n个数填在对角线的上,然后将各个格子填上对应对角线上的数的gcd值,也就是V[i][j]=gcd(V[i][i],V[j][j])

    题解:观察发现有很多重复的数,而且最大的那个数必然是对角线上的数。所以用map存数据,map.first 存数,map.second存次数。

        一开始发现了如果最大的数N重复x*x次,那么对角线上就有x个N,于是每次输出根号次最大的数,用这个规律wa23了(233)

        然后又发现了个规律,一次取一个最大值,然后将它与已经取出来的数做gcd得到x,易得x一定不在对角线上,且出现了2次,所以将它从map中erase掉(删去)。

        用这个规律可以得到以下算法,

        //一开始写得ifelse逻辑有点混乱。。。

    ac代码:

    #define  _CRT_SECURE_NO_WARNINGS
    #include<cstdio>  
    #include<algorithm>  
    #include<iostream>
    #include<string>
    #include<vector>
    #include<string.h>
    #include<map>
    using namespace std;
    typedef long long ll;
    const int maxn = 100 + 5;
    
    map<int, int> mp, ans;
    int gcd(int a, int b) {
        return b == 0 ? a : gcd(b, a%b);
    }
    int main() {
        int n;
        cin >> n;
        for (int i = 1; i <= n*n; i++)
        {
            int x;
            scanf("%d", &x);
            mp[x]++;
        }
        int total = n;
        while (total) {
            int now = 0;
            if (mp.rbegin()->second > 0) {
            now = mp.rbegin()->first, cout << now << ' ', total--, mp.rbegin()->second--; 
            for (auto j : ans)
                mp[gcd(now, j.first)] -= 2 * j.second;
            ans[mp.rbegin()->first]++;
            }
            else { mp.erase(mp.rbegin()->first); }      
            if (mp.empty() || total == 0)break;
        }
    }
    成功的路并不拥挤,因为大部分人都在颓(笑)
  • 相关阅读:
    局部变量、全局变量和修改全局变量
    python中函数的参数
    python之匿名函数和递归函数
    设计模式之职责链模式
    设计模式之代理模式
    设计模式之flyweight享元模式
    设计模式之外观模式
    设计模式之装饰模式
    组合模式更清晰的例子
    设计模式之组合模式
  • 原文地址:https://www.cnblogs.com/SuuT/p/8608656.html
Copyright © 2011-2022 走看看