码迷,mamicode.com
首页 > 其他好文 > 详细

poj 2635 千进制

时间:2015-03-03 23:28:42      阅读:195      评论:0      收藏:0      [点我收藏+]

标签:

转自: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 2635 千进制

标签:

原文地址:http://www.cnblogs.com/cnblogs321114287/p/4312091.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!