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