PAT(甲级)2021年春季考试 7-1 Arithmetic Progression of Primes (20 分)

PAT(甲级)2021年春季考试
7-1 Arithmetic Progression of Primes (20 分)

【题目描述】
In mathematics, an arithmetic progression (AP,等差数列) is a sequence of numbers such that the difference between the consecutive terms is constant. In 2004, Terence Tao (陶哲轩) and Ben Green proved that for any positive n, there exists at least one arithmetic progression consists of n consecutive prime numbers. For example, { 7,37,67,97,127,157 } is one solution for n=6. Now it is your job to find a maximum solution for a given n within a given range.

Input Specification:
Each input file contains one test case, which gives two positive integers in a line: n (≤10), the number of consecutive prime terms in an arithmetic progression, and MAXP (2≤MAXP<10 5), the upper bound of the largest prime in the solution.

Output Specification:
For each test case, if there exists a solution, print in ascending order the prime numbers in a line. If the solution is not unique, output the one with the maximum common difference. If there is still a tie, print the one with the maximum first number. If there is no solution bounded by MAXP, output the largest prime in the given range instead.

All the numbers in a line must be separated by a space, and there must be no extra space at the beginning or the end of the line.

Sample Input 1:

5 1000

Sample Output 1:

23 263 503 743 983

Sample Input 2:

10 200

Sample Output 2:

199

【解题思路】

输入n的范围最大只有10,我们可以暴力搜索。

首先打表生成2到MAXP的所有素数。

最大的公差可能值为(MAXP-2)/(n-1),我们从大往小搜索,判断是否符合条件,如果符合则记录答案,结束循环。

特判,如果n=1,或者不存在符合条件的等差数列,直接输出小于MAXP的最大的素数。

注意,这里我们将素数存在数组当中。如果使用vector,样例4会段错误,不知道原因。

【满分代码】

#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;
const int maxn=100005;
bool p[maxn];
int v[maxn];
int main()
{
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int n,m,size=0;
	cin>>n>>m;
	for(int i=2;i<=m;i++)
	{
		if(!p[i])
		{
			v[size++]=i;
			//vec.emplace_back(i);
			for(int j=2*i;j<=m;j+=i)
				p[j]=1;
		}
	}//素数打表 
	//cout<<size<<endl;
	int dif=(m-2)/(n-1),begin,d,found=0;
	if(n>1)
	{
		for(int i=dif;i>0;i--)
		{
			if(found) break;
			for(int j=size-1;j>0;j--)
			{
				int cnt=1,next=v[j]-i;
				while(p[next]==0&&next>=2)
				{
					cnt++;
					next-=i;
				}
				if(cnt>=n)
				{
					d=i;
					begin=v[j]-d*(n-1);
					found=1;
					break;
				}
			}
		}
	}
	if(found)
	{
		cout<<begin;
		for(int i=1;i<n;i++)
			cout<<" "<<begin+i*d;
		cout<<endl;
	}
	else
	{
		for(int i=m;i>=2;i--)
			if(!p[i])
			{
				cout<<i<<endl;
				break;
			}
	}
	return 0;
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

球王武磊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值