POJ 2635 The Embarrassed Cryptographer尴尬的译解密码者

2015年5月17日

题目大意,给你一个数K(4 <= K <= 10^100)和一个 L(2<=L<=10^6),K是由两个因子组成,若K最小的因子大于等于L,输出 GOOD,否则输出BAD和这个小于L的因子。多组输入,最多20组。

K这个数很大,不能用基本的数据类型处理,应用高精度来做,用一个字符数组来模拟。很容易想到的一个做法是,用高精度模拟出这个数,然后枚举K的因子x(2- L),若K除这个数x等于0,则就找到一个K的因子x,并且这个因子是小于L的,所以输出BAD x。若没有找到一个x能被K整除,则输出GOOD。分析一下时间复杂 度,对于每个K需要枚举的数是2-L这个范围,这里就是100*10^6,还有20组测试数据,所以总的时间复杂度是O(20*100*10^6),题目限制是3000MS,很明 显这里是过不了的。这里有一个优化方法,就是用埃氏素筛法将2-10^6的素数筛 选出来放在prim[]数组里,对于每个K,只需枚举2-L之间的素数就可以了,这 样你还是不能AC。还可以做一个优化,用一个10^12进制的数来模拟这个K。

所以,解决此题的方法:高精度模拟,用埃氏素筛将2-10^5的数筛选出来,用10^12进制模拟。

贴出代码,供大家参考。

#include <cstdio>
#include <cstring>
#define maxn 1000007
#define MAXN 101
#define LL long long 
LL prim[maxn];
LL arr[MAXN];
bool is_prim[maxn];
int Init()
{
    for(int i = 2; i * i < maxn; ++i)
    {
        if(!is_prim[i])
            for(int j = 2 * i; j < maxn; j += i)
                is_prim[j] = true;
    }
    int pos = 0;
    for(LL i = 2; i < maxn; ++i)
        if(!is_prim[i]) prim[pos++] = i;
    return pos;
}
int main()
{
    int N = Init();
    char ch[MAXN];
    int L;
    while(scanf("%s%d", ch, &L), ch[0] != '0', L)
    {
        int len = strlen(ch), pos = 0, num = 12, p = len % num;
        LL val = 1;
        while(p--) val *= 10;
        for(int i = 0; i < len; i += num)
        {
            LL val = 0;
            for(int j = i; j < i + num && j < len; ++j)
                val = val * 10 + ch[j] - '0';
            arr[pos++] = val;
        }
        bool flag = true;
        for(int i = 0; prim[i] < L && i < N; ++i)
        {
            LL Mod = 0;
            for(int j = 0; j < pos; ++j)
            {
                if(j != pos - 1) Mod = (Mod * 1000000000000 + arr[j]) % prim[i];
                else Mod = (Mod * val + arr[j]) % prim[i];
            }
            if(Mod == 0)
            {
                printf("BAD %d\n", prim[i]);
                flag = false;
                break;
            }
        }
        if(flag) puts("GOOD");
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值