Uva1434 YAPTCHA(威尔逊定理应用)

来源:互联网 发布:科比2000年西决数据 编辑:程序博客网 时间:2024/05/21 06:33

  题目链接:http://uva.onlinejudge.org/index.phpoption=com_onlinejudge&Itemid=8&category=516&page=show_problem&problem=4180

  这个题目就是让计算的值,分析一下可以看的出来,就是让计算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]);
    }
}

原创粉丝点击