数论,千进制,高精度求模+同余模定理

原题连接:http://poj.org/problem?id=2635

题意:给定一个大数K,K是两个大素数的乘积。

  然后给定一个int内的数L。

  求这两个大素数中最小的一个是否小于L,如果小于则输出这个素数。

思路:

  1.Char格式读入k,然后把k转换为千进制kt,同时变为int型。(加快运算效率)。

    例如:k=1234567变为千进制就为:kt = [  1][234][567].

     为了方便,代码使用的是“局部有序,全局倒序”存放kt,即kt = [567][234][1  ]

  2.素数打表。

    注意打表的范围要比10^6大,否则当L = 10^6时会数组越界。

  3.高精度求模

    123对3取模可以通过同余模定理对大数‘分块’间接求模。

    先求1%3 = 1;

    然后(1*10+2)%3=0;

    最后(0*10+3)%3 = 0;

    那么就得到123%3 = 0;

    在千进制下只需将*10改为*1000即可。

参考博客:http://blog.csdn.net/lyy289065406/article/details/6648530

#include<cstdio>
#include<cstring>
#include<algorithm> 
#include<iostream>
using namespace std;

const int Max = 1000050;
int Kt[10000];     //千进制的K
int L;
int prime[Max];

//素数打表 
void PrimeTable(void){
    int num = 0;
    prime[num++]=2;
    
    for(int i = 3 ; i <=Max;i+=2)
    {
        bool flag = true;
        for(int j = 0 ; prime[j]*prime[j]<=i;j++)
        {
            if(!(i%prime[j]))
            {
                flag = false;
                break;
            }
        }
        if(flag)
            prime[num++]=i;
    } 
    return ;
} 

//高精度k对p求模 
bool mod(const int*k,const int p,const int len)
{
    int sq = 0;
    for(int i = len-1;i>=0;i--)        //千进制k是逆序存放 
    {
        sq = (sq*1000+k[i])%p;        //同余模定理 
    }
    if(!sq)        //k能整除p 
        return false;
    else
        return true;
}


int main(){
    PrimeTable();
    
    char K[10000];
    while(cin>>K>>L&&L)
    {
        memset(Kt,0,sizeof(Kt));
        int lenK = strlen(K);
        for(int i = 0 ; i < lenK;i++)        //把k转换为千进制kt,其中kt局部顺序,全局倒序 
        {                                    //如k = 1234567 = [  1]234][567],则kt = [567][234][1  ] 
            int pkt = (lenK+2-i)/3-1;
            Kt[pkt] = Kt[pkt]*10+(K[i]-'0');
        }
        int lenkt = (lenK+2)/3;
        
        bool flag = true;
        
        int pMin = 0;
        while(prime[pMin]<L)
        {
            if(!mod(Kt,prime[pMin],lenkt))            //判断KT能否被prime[pMin]整除 
            {
                flag = false;
                cout<<"BAD "<<prime[pMin]<<endl;
                break;
            }
            pMin++;
        }
        if(flag)
            cout<<"GOOD"<<endl;
    }
    return 0;
}

 

 

 

17:15:42

posted @ 2018-08-13 17:16  chase丶月光  阅读(365)  评论(0)    收藏  举报