• 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
    ",prime[pMin]);
    55                 break;
    56             }    
    57             pMin++;
    58         }    
    59         if(flag) printf("GOOD
    ");
    60     }    
    61     return 0;
    62 }
  • 相关阅读:
    函数声明 函数表达式 通俗解释
    javascript 作用域 通俗解释
    webpack 实用配置总结
    webapck html-loader实现资源复用
    webpack css打包为一个css
    网站banner图片制作(简易版)
    webpack 通用模块(每个页面都用到的js)编译
    webpack CommonsChunkPlugin 提取公共代码
    SQL Server索引
    如何判断http服务器是否支持range寻址
  • 原文地址:https://www.cnblogs.com/cnblogs321114287/p/4312091.html
Copyright © 2020-2023  润新知