zoukankan      html  css  js  c++  java
  • 2019.7.7 校内测试题 尴尬的密码员

     

    题目

      尴尬的密码员(crypto.cpp,128MB,1s)

    【问题描述】:

      年轻有为的密码员小 Y 已经成功为他现在的公司中一个拥有成千上万用户
    的大系统设计了一套加密模块。这个加密模块的密码是由两个素数的乘积产生,
    小 Y 确信这个密码很安全,因为还没有一种有效的方法对这样的乘积进行因数
    分解。
      然后小 Y 没有想到的是,密码的两个因数都应该是很大的,而不仅仅只要
    它们的乘积大。现在可以认为某些用户的密码是弱密钥。为了不被解雇,小 Y
    秘密地浏览所有用户的密码,检查它们是否足够强大,当然尤其要特别小心的检
    查老板的密钥。

    【输入文件】: 

      输入包含不超过 20 组的测试数据,每行一个测试数据含有两个整数 K 和 L
    (4 <= K <= 10^100、2 <= L <= 10^6),K 表示是由两个素数乘积得到的密码,L
    是破解密码者最想要密码最小因数的范围,输入由 K=0 L=0 结束。

    【输出文件】:

      对于每一个密码 K,如果它的最小一个因数 p<l< span="">,就输出”BAD p”;否则就

    输出”GOOD”,每个测试数据输出一行。
    【样例】

    【输入输出样例】:

      
      crypto.in
        143 10
        143 20
        667 20
        667 30
        2573 30
        2573 40
        0 0
      crypto.out
        GOOD
        BAD 11
        GOOD
        BAD 23
        GOOD
        BAD 31  

    【数据规模】:

        如上

    考试得分:  50

    主要算法 :  质数(质因数分解,欧拉素数筛)

     

    题干:

        将一个超大合数化为两个最小质数的乘积,求出其中最小的质数

    应试策略:

      1.枚举2-L中的质数

      2.如果K/(枚举的数)为质数的话,输出答案

       代码

    #include<math.h>
    #include<stdio.h>
    #include<stdlib.h>
    #define LL long long
    #define FORa(i,s,e) for(LL i=s;i<=e;i++)
    #define FORs(i,s,e) for(LL i=s;i>=e;i--)
    #define gc pa==pb&&(pb=(pa=buf)+fread(buf,1,10000,stdin),pa==pb)?EOF:*pa++
    #define File(name) freopen(name".in","r",stdin),freopen(name".out","w",stdout)
    
    using namespace std;
    static char buf[10000],*pa=buf,*pb=buf;
    inline LL read();
    
    LL K,L;
    bool Prime(int x)
    {
        FORa(i,2,sqrt(x))
            if(x%i==0)
                return 0;
        return 1;
    }
    void Solve()
    {
        FORa(i,2,L-1)
        {
            if(Prime(i)&&Prime(K/i)&&K%i==0)
            {
                printf("BAD %d
    ",i);
                return; 
            }
        }
        printf("GOOD
    ");
    }
    int main()
    {
        File("crypto");
        K=read(),L=read();
        while(K!=0&&L!=0)
        {
            Solve();
            K=read(),L=read();
        }
        return 0;
    }
    inline LL read()
    {
        register LL x(0);register LL f(1);register char c(gc);
        while(c<'0'||c>'9') f=c=='-'?-1:1,c=gc;
        while(c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=gc;
        return x*f;
    }

    非完美算法:  

        照搬应试策略

    正解:

      1.欧拉素数筛,质数算术基本定理

      2.求出2-L内的最小的质数,运用高精看K是否可以整除这个质数,可以就是答案

      代码

     

    #include<math.h>
    #include<stdio.h>
    #include<stdlib.h>
    #include<iostream>
    #include<cstring>
    #define LL long long
    #define FORa(i,s,e) for(LL i=s;i<=e;i++)
    #define FORs(i,s,e) for(LL i=s;i>=e;i--)
    #define File(name) freopen(name".in","r",stdin);freopen(name".out","w",stdout);
    
    const int N=1000000;
    int cnt,prime[N+1],v[N+1];
    string K;
    LL L;
    void Prime()
    {
        FORa(i,2,L)
        {
            if(!v[i]) v[i]=prime[++cnt]=i;
            FORa(j,1,cnt)
            {
                if(prime[j]>j|prime[j]*i>L) break;
                v[prime[j]*i]=prime[j];
            }
        }
    }
    bool Check(int x)
    {
        int f=1;
        while(1);
    }
    void Solve()
    {
        FORa(i,1,cnt)
        {
            if(Check(i))
            {
                printf("BAD %d
    ",i);
                return; 
            }
        }
        printf("GOOD
    ");
    }
    int main()
    {
        File("crypto");
        while(K!="0"&&L!=0)
        {
            Prime(),Solve();
            cin>>K;
            scanf("%d",&L);
        }
        return 0;
    }

    总结:

      欧拉素数筛类板子

  • 相关阅读:
    CSRF
    PHP XXE漏洞
    jumpserver安装与部署
    ELK
    docker pull下来的镜像放哪儿了?
    MobSF 框架安装使用部署
    加密流量分析
    Pόlya定理-学习笔记
    所有区间异或的和的 一个加强
    计算一个序列有多少个不同的01子序列
  • 原文地址:https://www.cnblogs.com/SeanOcean/p/11172687.html
Copyright © 2011-2022 走看看