2021PAT甲级春季考试题解 AC

写一次题解,是2021PAT甲级春季的真题,我今年考过,但是不是很理想,做到第三题,实在不会堆排序,直接交卷了,真是很遗憾。后来状态一直不是很好,买了acwing的网课,看了一段时间,yxc真的很强,代码老练沉稳简洁。我一直偷懒用STL的,人家大佬一直手写,但还是比代码便秘的我,更短更强。今天回顾一下,九月再考一次吧。题意:求一个size为n的素数等差数列,最大上边界为maxp,如果有多个,则取公差最大的,如果还有多个,取首项最大的.找不到就输出范围内最大素数。思路:用线性筛或者埃筛打一个素数表
摘要由CSDN通过智能技术生成

写一次题解,是2021PAT甲级春季的真题,我今年考过,但是不是很理想,做到第三题,实在不会堆排序,直接交卷了,真是很遗憾。后来状态一直不是很好,买了acwing的网课,看了一段时间,yxc真的很强,代码老练沉稳简洁。我一直偷懒用STL的,人家大佬一直手写,但还是比代码便秘的我,更短更强。
今天回顾一下,九月再考一次吧。
在这里插入图片描述

题意
求一个size为n的素数等差数列,最大上边界为maxp,如果有多个,则取公差最大的,如果还有多个,取首项最大的.找不到就输出范围内最大素数。
思路
用线性筛或者埃筛打一个素数表,降低一下遍历的复杂度。
然后从大到小枚举MAXP范围内的所有的素数。
等差从大到小枚举,如果能组成完整素数列,则更新我的数据,更新的唯一标准就是新素数列的公差比我更大,因为我已经保证了首项是从大到小的。
d≤MAXP−a/n−1,对n=1,特判一下,防止除零异常。

//
// Created by 江左 on 2021/8/18.
//

#include <iostream>
#include <vector>
const int N=100010;
using namespace std;
int n,p,dmax=-1,res;

vector<int> primes; //记忆下,范围内的素数
bool st[N];         // st[x]存储x是否被筛掉

void get_primes(int n)
{
   
    for (int i = 2; i <= n; i ++ )
    {
   
        if (!st[i]) primes.push_back(i);
        for (int j = 0; primes[j] <= n / i; j ++ )
        {
   
            st[primes[j] * i] = true;
            if (i % primes[j] == 0) break;
        }
    }
}
int main()
{
   
    scanf("%d %d",&n,&p);
    get_primes(p);
    if(n==1) {
   
        cout<<primes.back();return 0;
    }
    for(int i=primes.size()-1;i>=0;i--)
    {
   
        int a=primes[i];//首项
        for (int d = (p-a)/(n-1); d >=1 ; --d) {
    //d是公差
            bool f= true;
            int cnt=n-1,t=a;
            while(cnt--)
            {
   
                t+=d;
                if(st[t])//a[i]需要
                {
   
                    f=false;break;
                }
            }
            if(f)
            {
   
                if(d>dmax) dmax=d,res=a;
                break;
            }
        }
    }
    if(dmax==-1
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值