BZOJ 2257 [Jsoi2009]瓶子和燃料

题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2257

题意:给定 n 个瓶子的容量,选出其中k个,最大化 k 个瓶子之间无度量所能表达的最小体积。kn1000,容量 109

题解:
考虑两个瓶子(容量为ab),互相倒来倒去能表示的体积都是以两个瓶子容量生成的值ax+by,而(a,b)|ax+by,所以最小体积就是(a,b),推广到k个瓶子,题目即最大化k个瓶子的最大公因数。
考虑将每个数分解因数,找最大且出现至少k次的因数即可。
不考虑map的时间复杂度为 O(nmax{V})

代码:

#include <map>
#include <cstdio>
#include <algorithm>
using namespace std;
map<int, int> cnt;
int n, k, x, i;
int main()
{
    scanf("%d%d", &n, &k);
    while(n--)
    {
        scanf("%d", &x);
        for(i = 1; i * i < x; ++i)
            if(x % i == 0) ++cnt[i], ++cnt[x / i];
        if(i * i == x) ++cnt[i];
    }
    map<int, int>::iterator it = cnt.end(), jt = cnt.begin();
    for(--it, --jt; it != jt; --it)
        if(it -> second >= k)
        {
            printf("%d\n", it -> first);
            break;
        }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值