牛客小白月赛99 D题 又是一年毕业季

 题目链接:牛客小白月赛99_ACM/NOI/CSP/CCPC/ICPC算法编程高难度练习赛_牛客竞赛OJ

通过对题目分析我们可以知道,题目要求我们找到一个时间t,时间t不能被a[i]整除。也就是说,t的因子不能是a[i]。由此我们可以想到,什么数比较容易满足这个条件呢?诶!就是素数(只能被1和它本身整除的数)。但是怎么证明时间t一定是素数呢?

首先我们假设时间t是一个合数,且这个合数不能被a[i]整除。因为t是合数,所以它一定存在一个除了1和它本身以外的因子,假设这个因子是x,那么x也一定满足不能被a[i]整除这一条件。既然x也满足这一条件,并且题目要求我们找的是最小的满足不能被a[i]整除的数,而x<t,那么答案肯定不是t。所以可以证明我们要求的时间t一定不是合数。

不是合数那就是素数了(t不可能为0)。有什么方法可以帮我们找到不被a[i]整除的最小的素数呢?我们自然会想到素数筛算法。

由于n<=2e5,所以我们可以用一个数组prime存储2e5+1个素数。并且我们可以使用map给所有的a[i]打上标记,最后只需要遍历2e5+1个素数,如果prime[i]满足不被a[i]整除的条件,也就是mp[prime[i]]=0,那么prime[i]就是答案。

AC code:

#include<bits/stdc++.h>
using namespace std;
#define int long long 
int t;
bool vis[1000000005];
int prime[200005];//存储2e5个素数

void pri(int n) {//欧拉筛
    int sum = 0;
    for (int i = 2; i <= n; i++) {
        if (!vis[i]) prime[++sum] = i;
        if (sum > 2e5) break;//因为n<=2e5,所以最多存储2e5+1个素数就够了
        for (int j = 1; j <= sum && i * prime[j] <= n; j++) {
            vis[i * prime[j]] = 1;
            if (i % prime[j]==0) break;
        }
    }
}

signed main() {
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);

    cin >> t;

    pri(100000000);

    while (t--) {
        map<int, int>mp;

        int n;
        cin >> n;
        for (int i = 1; i <= n; i++) {
            int a;
            cin >> a;
            mp[a] = 1;//因为a[i]有可能是素数,所以把这个素数打上标记
        }

        for (int i = 1; i <= 200001; i++) {
            if (!mp[prime[i]]) {//如果这个素数不能a[i]整除,那么直接输出
                cout << prime[i] << '\n';
                break;
            }
        }
    }

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值