题目链接:https://syzoj.com/problem/448
内存限制:512 MiB 时间限制:1000 ms

题目描述

且随疾风前行,身后亦须留心
吾虽浪迹天涯,却未迷失本心


一天小P想要玩lol,但是他太菜了,必须和他的王者学长组队才能赢。
学长此时正在解一道叫loI的问题:
N个小兵,编号为1,2,3……N,你有N种技能,第i种技能可以消灭所有编号为i+1的倍数的小兵
问最少放多少个技能可以消灭至少k个小兵
为了使小P和学长玩上lol,请你尽快解决这道题

输入格式

一行两个整数N,k,含义如题目描述

输出格式

一个整数,表示最少放多少个技能可以消灭至少k个小兵

样例输入

8 7

样例输出

4

数据范围与提示

对于30%的数据,满足k<N≤20
对于另外30%的数据,满足N≤10,000,000且k=N−1
对于100%的数据,满足k<N≤10,000,000

解题思路

类似于素筛,先用一个小的数筛掉以它为因子的数,标记,直到消灭掉k个。

#include <stdio.h>
#include <string.h>
bool vis[10000005];
int main() {
#ifndef LOCAL
    freopen("lol.in", "r", stdin);
    freopen("lol.out", "w", stdout);
#endif
    int n, k, ans, num;
    while (~scanf("%d%d", &n, &k)) {
        ans = num = 0;
        memset(vis, false, sizeof(vis));
        for (int i = 2; i <= n + 1 && num < k; i++) {
            if (!vis[i]) {
                ans++;
                for (int j = i; j <= n && num < k; j += i) {
                    if (!vis[j]) {
                        num++;
                        vis[j] = true;
                    }
                }
            }
        }
        printf("%d\n", ans);
    }
    return 0;
}