这个题目就是让计算的值,分析一下可以看的出来,就是让计算1/3k+7加上(3k+6)!/3k+7的小数部分,是一个威尔逊定理的应用的题目。
威尔逊定理:当且仅当p为素数时:( p -1 )! ≡ -1 ( mod p )。
有含义:若p为素数,那么有( p -1 )!+1是p的整数倍,如此可知,若3k+7是一个素数,那么有(3k+6)+1!/3k+7是一个大于(3k+6)!/3k+7整数部分的整数,因此这一项的值就是1。由于威尔逊定理是一个充分必要条件,那么,若3k+7不是一个素数,就有(3k+6)+1!/3k+7和3k+6)!/3k+7的整数部分相同,这一项的值就是0。由此,这个题目就变成了一个简单的筛素数的题目,找到所有的满足3*k+7形式的素数,对应的第k项为1,其余项为0。
ac代码:
#include<iostream>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<algorithm>
#define maxn 1000010
using namespace std;
bool visit[maxn*3];
bool a[maxn];
int s[maxn];
void getprime(){
int i,j;
memset (visit,0,sizeof(visit));
memset (a,0,sizeof(a));
for (i=2;i<3*maxn;i++){
if (!visit[i]){
if ((i-7)%3==0){
a[(i-7)/3]=1;
}
for (j=i*2;j<3*maxn;j+=i){
visit[j]=1;
}
}
}
s[1]=0;
for (i=2;i<maxn;i++){
s[i]=s[i-1]+a[i];
}
}
int main(){
int n,t;
getprime();
scanf("%d",&t);
while (t--){
scanf("%d",&n);
printf("%d\n",s[n]);
}
}