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;
}