poj 2635 千进制

转自:http://www.cnblogs.com/kuangbin/archive/2012/04/01/2429463.html

大致题意:

给定一个大数K,K是两个大素数的乘积的值。

再给定一个int内的数L

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

 

解题思路:

首先对题目的插图表示无语。。。

 

高精度求模+同余模定理

 

1、  Char格式读入K。把K转成千进制Kt,同时变为int型。

把数字往大进制转换能够加快运算效率。若用十进制则耗费很多时间,会TLE。

千进制的性质与十进制相似。

例如,把K=1234567890转成千进制,就变成了:Kt=[  1][234][567][890]。

为了方便处理,我的程序是按“局部有序,全局倒序”模式存放Kt

即Kt=[890][567][234][1  ]  (一个中括号代表一个数组元素)

2、  素数打表,把10^6内的素数全部预打表,在求模时则枚举到小于L为止。

注意打表不能只打到100W,要保证素数表中最大的素数必须大于10^6,否则当L=100W且K为GOOD时,会因为数组越界而RE,这是因为越界后prime都是负无穷的数,枚举的while(prime[pMin]<L)循环会陷入死循环

3、  高精度求模。

主要利用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就可以了

 

 

算法思路:千进制表示已知数,进行高精度取余即可,不过大牛们说,百进制TLE,千进制AC,万进制WA,

 

Sample Input

143 10

143 20

667 20

667 30

2573 30

2573 40

0 0

Sample Output

GOOD

BAD 11

GOOD

BAD 23

GOOD

BAD 31

 1 #include<stdio.h>

 2 #include<string.h>

 3 const int MAXN=1000010;

 4 int prime[MAXN+1];

 5 int getPrime()

 6 {

 7     memset(prime,0,sizeof(prime));

 8     for(int i=2;i<=MAXN;i++)

 9     {

10         if(!prime[i]) prime[++prime[0]]=i;

11         for(int j=1;j<=prime[0]&&prime[j]<=MAXN/i;j++)

12         {

13             prime[prime[j]*i]=1;

14             if(i%prime[j]==0) break;

15         }    

16     }    

17     return prime[0];

18 }    

19 

20 int Kt[100];

21 int L;

22 char str[1000];

23 

24 bool mod(int *K,int p,int len)

25 {

26     int sq=0;

27     for(int i=len-1;i>=0;i--)

28       sq=(sq*1000+K[i])%p;

29     if(!sq) return false;

30     return true;

31 }    

32 int main()

33 {

34     getPrime();

35     

36     while(scanf("%s %d",&str,&L)!=EOF)

37     {

38         if(L==0&&strcmp(str,"0")==0) break;

39         int len=strlen(str);

40         memset(Kt,0,sizeof(Kt));

41         for(int i=0;i<len;i++)

42         {

43             int ii=(len+2-i)/3-1;

44             Kt[ii]=Kt[ii]*10+str[i]-'0';

45         }    

46         int lenKt=(len+2)/3;

47         bool flag=true;

48         int pMin=1;

49         while(prime[pMin]<L)

50         {

51             if(!mod(Kt,prime[pMin],lenKt))

52             {

53                 flag=false;

54                 printf("BAD %d\n",prime[pMin]);

55                 break;

56             }    

57             pMin++;

58         }    

59         if(flag) printf("GOOD\n");

60     }    

61     return 0;

62 }

 

你可能感兴趣的:(poj)