POJ2635 The Embarrassed Cryptographer (同余)

来源:互联网 发布:java抽象工厂模式例子 编辑:程序博客网 时间:2024/06/05 20:16

题目大意:给出一个大数K<=10^180,再给出一个数L<=10^6;K是由2个素数相乘得来的,如果K的任一个素数小于L则输出bad 和小于L的这个素数,或者2个因子都小于L的时候输出最小的因子。

思路:大数取余。为了避免TIE使用了1000进制。因为只是一次运算所以不必逆置数组。说实在的,10进制想不通为什么会TIE啊~~囧~~求大牛指教啊~~现在的计算机1s不是已经能处理10^8的执行次数了吗?10进制一个100W的素数就只是n*logn的算法就只是2*10^7次执行次数嘛~~下面的枚举素数的时候,n*m的算法嘛~~100w内的素数个数只有78498个嘛~~就10^5嘛~~即n为10^5嘛~~m就是大数的数位啊~~最多180嘛~~不就是总共10^7执行次数嘛~~所以在2s内竟然无限TIE我真的想不通~~~囧。。

大数取模用到了关键定理:(来自小优博客)

高精度求模。

主要利用Kt数组和同余模定理。

例如要验证123是否被3整除,只需求模124%3

但当123是一个大数时,就不能直接求,只能通过同余模定理对大数“分块”间接求模

具体做法是:

先求1%3 = 1

再求(1*10+2)%3 = 0

再求 (0*10+4)% 3 = 1

那么就间接得到124%3=1,这是显然正确的

而且不难发现, (1*10+2)*10+4 = 124

这是在10进制下的做法,千进制也同理,*10改为*1000就可以了

 


program:#include<iostream>#include<stdio.h>#include<string.h>#include<math.h>#include<algorithm>using namespace std; char mm[200];int tmp[200]; int tt[50][2];int prime[100000];int flag[1000010]; //这个数组大小坑死我,晕。WA了2次 int pp;int prk,k;int start1,start2; int get_remainder(int p){      int rr,bb=1000;    for(int i=0;i<start2;i++)//老是出现++的问题    {            if(i==0)      {         rr=tt[i][0]%p;//先计算数组下标第一项                              }      else         {                                                 rr=(rr*1000+tt[i][0])%p; //后面的就可以由前面的推出来了         }      //cout<<"i tt[i][0]  rr  "<<i<<' '<<tt[i][0]<<' '<<rr<<endl;         //system("pause");            }       if(rr==0) return 0;   return 1;         } int main(){prk=0; for(__int64 i=2;i<1000010;i++){   if(!flag[i])   {    prime[prk++]=i;    for(__int64 g=i*i;g<1000010;g+=i)//以后还是用2 个64int好了。       flag[g]=1;                  }        }//cout<<prime[prk-1]<<endl;//cout<<prime[prk-2]<<endl;//cout<<prk<<endl; while(scanf("%s%d",mm,&pp)!=EOF){  if(mm[0]=='0'&&pp==0)break;   int len=strlen(mm);  for(int i=0;i<len;i++)  {     tmp[i]=mm[i]-'0';         }   int cur=len%3;  int tmppp=0;   if(cur!=0)                   //提前把前面不为3的整数倍的部分提取出来     {                  for(int i=0;i<cur;i++)             tmppp=tmppp*10+tmp[i];        tt[0][0]=tmppp;          }   start1=0,start2=0;   if(cur!=0){  start1=cur;  start2=1;}    int tmt=1;  tmppp=0;   for(int i=start1;i<len;i++)//把转换成1000进制的数放到2维数组里面  {     tmppp=tmppp*10+tmp[i];      if(tmt==3)     {       tt[start2++][0]=tmppp;               tmppp=0;       tmt=1;             }     else tmt++;        }  //for(int i=0;i<start2;i++)/////     //  cout<<tt[i][0]<<' '<<endl;  int i=0;   for(;i<prk && prime[i]<=pp;i++)//枚举  {     //cout<<"prime[i]  "<<prime[i]<<' '<<endl;    if(get_remainder(prime[i])==0)       break;          }            if(prime[i]<pp)///        printf("BAD %d\n",prime[i]) ;  else if(prime[i]==pp || prime[i]>pp)       printf("GOOD\n") ;                                                           }system("pause"); return 0;} 


 

小优的博客说的很详细:http://blog.csdn.net/lyy289065406/article/details/6648530

原创粉丝点击