来源: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; }