POJ 2635 The Embarrassed Cryptographer (同余线性方程+素数筛)

题目地址:POJ 2635

先用素数筛把10^6万以内素数筛出来。然后把输入的那个大数转化成数组,并且每三位存成一个数,这样可以节约内存和时间,然后利用同余线性的原理,对那个小整数以内的所有素数枚举,然后判断是否整除,找到最小的能被整除的。

代码如下:

#include <iostream>
#include <string.h>
#include <math.h>
#include <queue>
#include <algorithm>
#include <stdlib.h>
#include <map>
#include <set>
#include <stdio.h>
using namespace std;
#define LL __int64
#define pi acos(-1.0)
const int mod=100000000;
const int INF=0x3f3f3f3f;
const double eqs=1e-8;
char s[200];
int num[40], prime[150000], tot, check[2100000], cnt;
void init()
{
        tot=0;
        int i, j;
        memset(check,0,sizeof(check));
        for(i=2; i<=2000000; i++) {
                if(!check[i]) {
                        prime[tot++]=i;
                }
                for(j=0; j<tot; j++) {
                        if(i*prime[j]>=2000000) break;
                        check[i*prime[j]]=1;
                        if(i%prime[j]==0) break;
                }
        }
        //printf("%d\n",tot);
}
void chai()
{
        int i, ans, len=strlen(s), j;
        cnt=0;
        for(i=len-1; i>=0; i-=3) {
                ans=0;
                for(j=i-2; j<=i; j++) {
                        if(j>=0) {
                                ans=ans*10+s[j]-'0';
                        }
                }
                num[cnt++]=ans;
        }
}
bool Judge(int x)
{
        int ans=0;
        for(int i=cnt-1; i>=0; i--) {
                ans=(ans*1000+num[i])%x;
        }
        return !ans;
}
int main()
{
        int b, i, j, flag;
        init();
        while(scanf("%s%d",s,&b)!=EOF&&s[0]!='0') {
                flag=0;
                chai();
                for(i=0; i<tot; i++) {
                        if(prime[i]>=b) break;
                        if(Judge(prime[i])) {
                                flag=1;
                                break;
                        }
                }
                if(!flag) puts("GOOD");
                else
                        printf("BAD %d\n",prime[i]);
        }
        return 0;
}
时间: 2024-10-25 11:19:43

POJ 2635 The Embarrassed Cryptographer (同余线性方程+素数筛)的相关文章

poj 2635 The Embarrassed Cryptographer

题目链接:http://poj.org/problem?id=2635 思路:当看到K的最大值为 10100 的第一想法就是用java打大数,建立一个素数表,然后再在素数表中去找,看是否有符合条件的. code: import java.math.*; import java.util.*; public class ggg { public static void main(String[] args) { int len=0; Scanner cin=new Scanner(System.i

[ACM] POJ 2635 The Embarrassed Cryptographer (同余定理,素数打表)

The Embarrassed Cryptographer Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 11978   Accepted: 3194 Description The young and very promising cryptographer Odd Even has implemented the security module of a large system with thousands of

poj 2635 The Embarrassed Cryptographer (同余定理,筛选法)

链接:poj 2635 题意:给定一个大数k,k是两个大素数的乘积的值,再给定一个int内的数L 问这两个大素数中最小的一个是否小于L,如果小于则输出这个素数. 分析:因为k达到了10^100,只能用字符串读入,再转化为千进制,用int数组存储, 然后枚举小于L的素数,看是否能被整除,即判断k%L是否为0, 这样就得先用筛选法求素数打表,但是注意要打表到大于10^6 关于高精度取余,就需要用到同余定理 如 123456%N=(((123%N)*1000%N)+456)%N #include<st

POJ 2635 The Embarrassed Cryptographer(高精度取模 + 同余模定理)

The Embarrassed Cryptographer Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 12905   Accepted: 3472 Description The young and very promising cryptographer Odd Even has implemented the security module of a large system with thousands of

poj 2635 The Embarrassed Cryptographer 筛素数+高精度除法

题意: 给K(<10^100),L(<10^6),求K小于L的最小素因子并输出,如果没有则输出GOOD. 分析: 枚举小于L的素数用高精度除法判断是否是因子,关键是怎么高效筛素数,先给一种比较慢的筛法: primes[max_prime_num],num=0; memset(vis,0,sizeof(vis)) for(int i=2;i<maxL;++i) if(vis[i]==0){ prime[num++]=i; for(int j=2*i;j<maxL;j+=i) vis[

POJ 2635 The Embarrassed Cryptographer(大数求余)

题意:给出一个大数,这个大数由两个素数相乘得到,让我们判断是否其中一个素数比L要小,如果两个都小,输出较小的那个. 分析:大数求余的方法:针对题目中的样例,143 11,我们可以这样算,1 % 11 = 1:      1×10 + 4 % 11 = 3:      3×10 + 3 % 11 = 0;我们可以把大数拆成小数去计算,同余膜定理保证了这个算法的这正确性,而且我们将进制进行一定的扩大也是正确的. 注意:素数打标需要优化,否则超时.   进制需要适当,100和1000都可以,10进制超

POJ 2635 The Embarrassed Cryptographer 线性筛+高精度取模

题目大意:给两个数,第一个数的范文是10^100,第二个数10^6,第一个数是两个质数的乘积,问有没有不超过第二个数的数是第一个树的因子. 思路:10^6中只有7w+个素数,只要挨个判定能不能整除即可.然后这个题素数必须线性,不然就T.还有高精度一开始我压了4位,之后就wa,调了很长时间发现判断整除的过程中爆int了,换成long long就是T,最后十分生气,直接压到了7位,果断A了,好像时间还不慢.如果要用int的话,最多只能压3位,应该也能过. CODE: #include <cmath>

【阔别许久的博】【我要开始攻数学和几何啦】【高精度取模+同余模定理,*】POJ 2365 The Embarrassed Cryptographer

题意:给出一大数K(4 <= K <= 10^100)与一整数L(2 <= L <= 106),K为两个素数的乘积(The cryptographic keys are created from the product of two primes) 问构成K的最小素数是否绝对小于L,若是,则输出BAD p,p为最小素数,否则输出GOOD; 分析:从小到大枚举1~10^6内的素数p,while(p<L)时,判断K是否能被p整除,若能则证明构成K的最小素数绝对小于L,反之则大于L

POJ 2635-The Embarrassed Cryptographer(高精度求模+同余模定理)

The Embarrassed Cryptographer Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Practice POJ 2635 Appoint description:  System Crawler  (2015-05-28) Description The young and very promising cryptographer Odd E