Less Prime
Let n be an integer, 100 n 10000, nd the prime number x, x n, so that n p x is maximum,
where p is an integer such that p x n < (p + 1) x.
Input
The rst line of the input contains an integer, M, indicating the number of test cases. For each test
case, there is a line with a number N, 100 N 10000.
Output
For each test case, the output should consist of one line showing the prime number that veries the
condition above.
Sample Input
5
4399
614
8201
101
7048
Sample Output
2203
311
4111
53
3527
题意:给出一个n,问:n-p*x 取最大值时x的值是多少,其中p满足p*x<=n<(p+1)*x。
根据p*x<=n<(p+1)*x可以得出n-px的值一定小于x,所以对n-p*x模x后有:(n-p*x)%x=n-p*x=n%x,所以现在只要求出n%x的最大值即可。
我们先用素数筛筛出所有小于10000的素数,之后找出最接近n的临界素数(保险起见可以找出小于n的最大素数然后取大于该素数的下一个素数),从这个邻接素数从后往前遍历所有素数,这里有一个剪枝就是当我们正在遍历的素数小于n%x时可以直接退出循环,因为我们要的是n%x的最大值,如果当前遍历的素数小于这个最大值,那么显然由这个素数推出的n%x一定小于当前的最大值,而往后比这个素数小的素数更是如此,因此可以直接退出循环。
AC code:

#include<bits/stdc++.h>
using namespace std;
int su[11005];
bool u[11005];
int num;
void olas()
{
num=1;
memset(u,true,sizeof(u));
for(int i=2;i<=11000;i++)
{
if(u[i]) su[num++]=i;
for(int j=1;j<num;j++)
{
if(i*su[j]>11000) break;
u[i*su[j]]=false;
if(i%su[j]==0) break;
}
}
}
int main()
{
//freopen("input.txt","r",stdin);
int t;
olas();
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
int id=(lower_bound(su+1,su+num+1,n)-su+1);
int tmp1=0,tmp2=0;
for(int i=id;i>0;i--)
{
if(su[i]<=n&&n%su[i]>tmp2)
{
tmp1=su[i];
tmp2=n%su[i];
}
if(su[i]<tmp1) break;
}
printf("%d\n",tmp1);
}
return 0;
}
