USACOHumble Numbers

来源:http://www.nocow.cn/index.php/Translate:USACO/humble

这题看数据规模,只能用O(NlogN)算法了,而且只能逐个数生成。

如何从已经生成的丑数中生成新的丑数,并且严格按照递增规律生成,这是主要解决的问题。

很明显,把已有的丑数乘上一个质数p就得到了新的丑数,这样一个BFS的算法很容易想到,但是判重和判断是否按照严格递增的顺序生成,这个写起来麻烦,而且效率不好,至于用优先队列或者堆来优化BFS,就更加繁琐了。

这里参考了nocow上的题解,使用了STL里的set,这里简单介绍下set:

1.set,就是集合,集合里的元素不存在重复;

2.set中的元素是有序的;

3.set的插入,查找和删除功能都是O(lonN)的。

很明显,这题简直是为set而设立的!我们可以不断的把生成好的丑数存入set中,当set的size大于给定的size时我们就把set中最大的数删除,然后继续生成,直到再也无法生成为止。

/*
ID:ay27272
PROG:humble
LANG:C++
*/

#include <iostream>
#include <cstdio>
#include <set>
using namespace std;

set<int> d;
int a[105];

int main()
{
    freopen("humble.in","r",stdin);
    freopen("humble.out","w",stdout);
    d.clear();
    int m,n;
    cin>>n>>m;
    for (int i=1;i<=n;i++)
    {
        cin>>a[i];
        d.insert(a[i]);
    }
    for (int i=1;i<=n;i++)
    {
        set<int>::iterator it=d.begin();
        while (true)
        {
            int t=(*it)*a[i];
            if (t<0) break;
            if (d.size()>m)
            {
                d.erase(--d.end());   //把超出范围的数删除
                if (t>(*(--d.end()))) break;  //这里边的“--”主要是因为set是从0开始存储的,不减的话会RTL,但是这里不会改变d.end()的值,最后的输出同理
            }
            d.insert(t);
            it++;
        }
    }
    cout<<*(--d.end())<<endl;
    return 0;
}
原文地址:https://www.cnblogs.com/ay27/p/2807910.html