本文共 1016 字,大约阅读时间需要 3 分钟。
传送门
题目大意:求区间 [m,n] 中幸运数的个数。
锦囊2:从左到右扫描,用一个堆来处理,堆的每一项记录下要删的倍数和当前删到的值,以当前删到的值建小根堆。每次取出一个数,加上一次倍数再放回去。枚举每一个数,如果这个数被跳过了就枚举下一个,如果没被跳过就找到了一个幸运数,把它的两倍加入堆。2的倍数可以特别处理一下。
思路:因为提示用堆来做,我第一反应是用优先队列来做,但是发现优先队列不能很方便的按照下标遍历……GG……
正确的姿势是配合DFS暴力模拟,先去除下标为2的倍数的数,得到所有奇数。然后在此基础上,去除下标是当前位置数 x 的倍数的数,完成之后得到所有的幸运数。统计其中位于所求区间内的数的个数即可。
代码:
#include#include int m, n;int a[1000010];void dfs(int dep) { int cnt = dep; if (a[dep] > n) return; for (int i = dep; i <= n; i++) { if (i % a[dep] != 0) { a[cnt++] = i; } if (cnt >= n) break; } if (dep + 1 > n) return; dfs(dep + 1);}int main() { int i, ans = 0; while (scanf("%d%d", &m, &n) != EOF) { for (i = 1; i <= n; i++) { a[i] = 2 * i - 1; } dfs(2); i = 1; while (a[i] <= n) { if (a[i] >= m) { ans++; } i++; } printf("%d\n", ans); } return 0;}
这个代码实现了DFS暴力模拟的思路,首先预处理所有奇数,然后递归地去除下标为倍数的数,最后统计区间内的幸运数个数。
转载地址:http://tudwz.baihongyu.com/