zoukankan      html  css  js  c++  java
  • Luogu4571 [JSOI2009]瓶子和燃料(裴蜀定理)题解

    前置芝士

    裴蜀定理

    (a)(b)是整数,且(gcd(a,b)=d),那么对于任意的整数(x)(y)(ax+by)都一定是(d)的倍数,特别地,一定存在整数(x)(y),使(ax+by=d)成立。

    推广: (a_1,a_2,a_3...a_n)(n)个整数,(d)是它们的最大公约数,那么存在整数(x_1...x_n)使得(x_1 imes a_1+x_2 imes a_2+...x_n imes a_n=d)

    思路

    根据裴蜀定理,外星人所给出的燃料数量为(k)个瓶子容积的(gcd)。因此问题就转化为:从(n)个数中选出(k)个数,使得它们的(gcd)最大。

    我们可以将每个数的因数分解出来(并不只是质因数),记录每一个因子的出现次数,排序以后选出最大的出现次数(geq k)的就可以了。

    另外,本题数值较大,需要开(map)

    参考代码

    #include <cstdio>
    #include <algorithm>
    #include <map>
    
    using namespace std;
    
    const int maxn = 1e6 + 10;
    int n,cnt,k;
    struct Num{
        int val,num;
    }p[maxn];
    map<int,int> T;
    
    bool cmp(Num x, Num y){return x.val > y.val;}
    
    int main(){
        scanf("%d%d", &n, &k);
        for(int i = 1; i <= n; ++ i){
            int v; scanf("%d", &v);
            for(int j = 1; j * j <= v; ++ j){
                if(v % j == 0){
                    if(!T[j]) T[j] = ++ cnt, p[cnt].val = j, p[cnt].num ++;
                    else p[T[j]].num ++;
                    int fff = v / j;
                    if(fff == j) continue;
                    if(!T[fff]) T[fff] = ++ cnt, p[cnt].val = fff, p[cnt].num ++;
                    else p[T[fff]].num ++;
                }
            }
        }
        sort(p + 1, p + 1 + cnt, cmp);
        for(int i = 1; i <= cnt; ++ i)
            if(p[i].num >= k) return printf("%d
    ", p[i].val), 0;
        return 0;
    }
    
  • 相关阅读:
    hibernate 映射<二>一对一主键关联
    C# Convert Type to T
    008 OS模块
    001基础知识补充与拓展
    005Buffer(缓冲区)
    009path模块
    002nodejs简介与安装
    007http模块
    004NPM包管理器
    003nodejs的模块化
  • 原文地址:https://www.cnblogs.com/whenc/p/13979008.html
Copyright © 2011-2022 走看看