poj2635--The Embarrassed Cryptographer(数论篇1,大数取模)

The Embarrassed Cryptographer

Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 12496   Accepted: 3330

Description

The young and very promising cryptographer Odd Even has implemented the security module of a large system with thousands of users, which is now in use in his company.
The cryptographic keys are created from the product of two primes, and are believed to be secure because there is no known method for factoring such a product effectively.

What Odd Even did not think of, was that both factors in a key should be large, not just their product. It is now possible that some of the users of the system have weak keys. In a desperate attempt not to be fired, Odd Even secretly goes through all the users
keys, to check if they are strong enough. He uses his very poweful Atari, and is especially careful when checking his boss‘ key.

Input

The input consists of no more than 20 test cases. Each test case is a line with the integers 4 <= K <= 10100 and 2 <= L <= 106. K is the key itself, a product of two primes. L is the wanted minimum size of
the factors in the key. The input set is terminated by a case where K = 0 and L = 0.

Output

For each number K, if one of its factors are strictly less than the required L, your program should output "BAD p", where p is the smallest factor in K. Otherwise, it should output "GOOD". Cases should be separated by a line-break.

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

Source

Nordic 2005

题目要求:给出两个数k和l,k是由两个素数相乘得到,如果素数小于l,输出BAD 和那个素数,否则输出GOOD。

先打出素数表,其中一定要有大于100万的素数,把在l内的素数与k去模,其中k是10^100用到大数取余,将k分为三位数的段a[0] a[1],在计算

temp = a[0]%phi[i]

temp = (a[1]*1000+temp)%phi[i]

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std ;
#define LL __int64
char str[200] ;
int n , a[100] , num ;
int vis[2100000] , phi[1100000] , cnt ;
void init()
{
    int i , j ;
    cnt = 0 ;
    memset(vis,0,sizeof(vis)) ;
    for(i = 2 ; i <= 2000000 ; i++)
    {
        if( !vis[i] ) phi[cnt++] = i ;
        for(j = 0 ; j < cnt ; j++)
        {
            if( i*phi[j] >= 2000000 )
                break ;
            vis[i*phi[j]] = 1 ;
            if( i%phi[j] == 0 )
                break ;
        }
    }
}
int f(int k)
{
    LL sum = 0 , i , l ;
    for(i = num-1 ; i >= 0 ; i--)
    {
        sum = sum*1000 + a[i] ;
        sum %= k ;
    }
    if( sum == 0 )
        return 1 ;
    return 0;
}
int main()
{
    int i , j , l , flag , s ;
    init() ;
    while( scanf("%s %d", str, &n) != EOF )
    {
        if( strlen(str) == 1 && str[0] == '0' && n == 0 ) break ;
        l = strlen(str) ;
        memset(a,0,sizeof(a)) ;
        num = 0 ;
        flag = 0 ;
        for(i = l-1 ; i >= 0 ; i--)
        {
            flag++ ;
            if( flag == 3 )
            {
                a[num] = (str[i]-'0')*100 + (str[i+1]-'0')*10 + ( str[i+2] -'0' ) ;
                num++ ;
                flag = 0 ;
            }
        }
        if( flag == 1 )
            a[num++] = str[0] - '0' ;
        else if( flag == 2 )
            a[num++] = (str[0] - '0') * 10 + str[1] - '0' ;
        for(i = 0 ; i < cnt ; i++)
        {
            if( phi[i] >= n ) break ;
            if( f(phi[i]) )
                break ;
        }
        if( phi[i] >= n || i == cnt )
            printf("GOOD\n") ;
        else
            printf("BAD %d\n", phi[i]);
    }
    return 0;
}

时间: 2024-10-13 17:15:28

poj2635--The Embarrassed Cryptographer(数论篇1,大数取模)的相关文章

快速幂+大数取模

快速幂+大数取模 快速幂,其实就是求(a^b)% p,(其中a,b,p都比较大在int范围内)这类问题. 首先要知道取余的公式:(a*b)%p=(a%p*b%p)%p. 那么幂不就是乘机的累积吗,由此给出代码: int fast(int a,int b,int p) {   long long a1=a,t=1; while(b>0) { if(b&1)          /如果幂b是奇数多乘一次,因为后边会除2变偶数,(7/2=3) t=(t%p)*(a1%p)%p; a1=(a1%p)*

csu 1556: Jerry&#39;s trouble(大数取模)

题意:求出1^m+2^m+...n^m 思路:直接套用模板 #include<cstdio> #include<iostream> #include<cstring> #include<cmath> #include<stdlib.h> #include<algorithm> #include<queue> #include<stack> #include<ctype.h> #define LL l

大数取模

//大数取模 #include "cmath" #include "iostream" #include "string.h" using namespace std; int mod(char str[],int num) { int number[100]; for(int i=0;i<strlen(str);i++) number[i]=str[i]-'0'; int remainder=0; for(int i=0;i<str

hdu2302(枚举,大数取模)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2303 题意:给出两个数k, l(4<= k <= 1e100, 2<=l<=1e6):其中k是两个素数的乘积,问k是否存在严格小于l的因子,若有,输出 BAD 该因子,反之输出GOOD: 思路: 先1e6内素数打表,再枚举一个因子,判断因子用大数取模: 代码: 1 #include <iostream> 2 #include <stdio.h> 3 #inclu

POJ 1426 Find The Multiple(大数取模)【DFS】||【BFS】

<题目链接> 题目大意: 给一个小于200的正整数n,问只有0和1组成的位数小于100的最小能被n整除的数是多少. 解题分析: 用DFS或者BFS沿着位数进行搜索,每一次搜索到下一位都有两种情况,0或者1,还要注意的是,大数取模的方法.但是我有一个疑问,这题位数最高为100,用dfs为什么不会超时?还是说只是此题数据太弱吗? BFS解法 #include<iostream> #include<cstdio> #include<queue> #include&

机试真题 大数取模运算

之前总结过,大数问题,取模就是取商取余数: #include<iostream> #include<stdlib.h> #include<string> using namespace std; string devide(int& r, string s, int n) { string ss = ""; for (int i = 0; i < s.size(); i++) { int temp = r*10 + int(s[i] -

POJ2635 The Embarrassed Cryptographer 简单数论

题目链接 看到这题的示意图也是醉了~题意:给你一个k,他是两个素数之积,然后给了一个数字L,然后找到具体是哪两个素数相乘等于k,较小的那个素数是否小于L,若小于L就输出 "BAD"外加较小的那个素数,否则就输出"GOOD", 刚拿到这题目,有些钻牛角尖外加题意没看清楚,一开始纠结于 K很大,若想具体找出两个素数不可能,因为总有一个很大很大,求出其中一个素数 是否在10^6内是可以的,但是那时候我觉得还需要证明 k/prime  的值必须也是素数才符合要求,其实题目都

hdu 1212 Big Number(大数取模)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1212 Big Number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 7083    Accepted Submission(s): 4884 Problem Description As we know, Big Number is

hdu1212(大数取模)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1212 题意:给出两个数a, b,求a%b: 思路:(c+d)%e=c%e+d%e,(c*d)%e=(c%e*d%e)%e: 代码: 1 #include <iostream> 2 #include <stdio.h> 3 #include <string.h> 4 #define ll long long 5 #define MAXN 1000+10 6 using nam