题目大意:给出一个大数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.youkuaiyun.com/lyy289065406/article/details/6648530