zoukankan      html  css  js  c++  java
  • 1402Vigenère密码(Noip2012提高组第1题)

    维吉尼亚密码:人们在单一恺撒密码的基础上扩展出多表密码,称为“维吉尼亚”密码。该方法最早记录在吉奥万·巴蒂斯塔·贝拉索( Giovan Battista Bellaso)于1553年所著的书《吉奥万·巴蒂斯塔·贝拉索先生的密码》(意大利语:La cifra del. Sig. Giovan Battista Bellaso)中。

    我大概花了1.5h写出的代码,老同志写代码慢,你们写估计40-50min↓↓↓↓  缺点:审题不清,代码量大,算法不够严谨,代码运行时间长。。。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<string>
     4 #include<cstring>
     5 using namespace std;
     6 char a[30][30];
     7 char k[1200],m[1200];
     8 /*step3:密钥和密文来查找明文函数的编写*/
     9 char chazhao(char c1,char c2)
    10 {
    11     int x,y;
    12     //下面循环实现行查找 
    13     for(int i=1;i<=26;i++)
    14     {
    15         if(a[i][1]==toupper(c1))
    16         {
    17             x=i;
    18             break;
    19         }
    20     } 
    21     //下面循环实现通过行号和密文结果来找明文 
    22     for(int i=1;i<=26;i++)
    23     {
    24         if(a[x][i]==toupper(c2))
    25         {
    26         y=i;
    27         break;    
    28         }
    29     }
    30     //大小写对应 
    31     if(c2>='A'&&c2<='Z')return char('A'+y-1);
    32     else return char('a'+y-1);
    33 }
    34 int main()
    35 {
    36     char c='A';
    37     for(int i=1;i<=26;i++)
    38     {
    39         for(int j=1;j<=26;j++)
    40         {    
    41             a[i][j]=c;
    42             c++;
    43             if(c=='[')c='A';
    44         }
    45         c++;
    46         if(c=='[')c='A';    
    47     }
    48     /*step1:构造运算规则表,完成之后可以单独测试*/
    49     gets(k);
    50     gets(m);
    51     int lk=strlen(k),lm=strlen(m);
    52     int kk=lk,n=0;
    53     while(kk<lm)
    54     {
    55         k[kk++]=k[n++];
    56         if(n==lk)n=0;
    57     }
    58     /*step2:让密钥和密文长度一样的放在两个数组中,这样就可以方便下一步一次循环实现*/
    59     for(int i=0;i<lm;i++)cout<<chazhao(k[i],m[i]);
    60     return 0;
    61 } 

    网上其他题解↓↓↓↓↓↓↓简短,代码量少。。。算法严谨

    本表指 一对密钥与原文可以加密成密文,现在要翻译密文,也就是知道对应的点,也知道了y轴坐标,求x轴坐标。
    1.当密文≥密钥时,我们发现数据是依次递增的,则此时ans[i]= miwen[i]-key[j]+'a'
    2.当密文<密钥时,数据由最右端向左依次递减,此时ans[i]= 'z'-(key[j]-miwen[i]-1)
    j的意义在后面。
    注意这里还有一个易错点,密钥的长度可能小于密文的长度,那么当密钥较短时就要运用循环多次使用此密钥
    int j=0;
     并且在每次循环后
    j++;
    if(j==strlen(key))
          j=0;
    最后通过miwen_x[i]的值将原文的大小写形式恢复原样
    这样就解决此问题了
    本题总思路:
    1.读入密钥、密文并转换成小写(大写也可),同时记录密文的大小写情况
    2. 运用算法算出原文
    3.通过大小写情况恢复原文的大小写

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<math.h>
    
    int change(int i)//大小写转换 
    {
        return (i>='A'&&i<='Z')?i+'a'-'A':i;
    }
    
    
    int main()
    {
        char key[120];
        char miwen[1200];
        int miwen_x[1200];//密文大小写 1小写 2大写 
        scanf("%s %s",key,miwen);
        int len=strlen(key);
        for(int i=0;i<=len-1;i++)
            key[i]=change(key[i]);
        for(int i=0;i<=strlen(miwen)-1;i++)
        {
            if(miwen[i]>='A'&&miwen[i]<='Z')
                miwen_x[i]=2;
            else
                miwen_x[i]=1;
            miwen[i]=change(miwen[i]);
        }
        
        char ans[1200];
        int j=0;
        for(int i=0;i<=strlen(miwen)-1;i++)
        {
            if(miwen[i]>=key[j])
                ans[i]=miwen[i]-key[j]+'a';
            else
                ans[i]='z'-(key[j]-miwen[i]-1);
            if(miwen_x[i]==2)
                ans[i]=ans[i]-('a'-'A');
            j++;
            if(j==len)
                j=0;
        }
        ans[strlen(miwen)]=0;
        printf("%s",ans);
        
                
        return 0;
    }
     1 #include<stdio.h>
     2 #include<stdlib.h>
     3 #include<string.h>
     4 #include<math.h>
     5 
     6 int change(int i)//大小写转换 
     7 {
     8     return (i>='A'&&i<='Z')?i+'a'-'A':i;
     9 }
    10 
    11 
    12 int main()
    13 {
    14     char key[120];
    15     char miwen[1200];
    16     int miwen_x[1200];//密文大小写 1小写 2大写 
    17     scanf("%s %s",key,miwen);
    18     int len=strlen(key);
    19     for(int i=0;i<=len-1;i++)
    20         key[i]=change(key[i]);
    21     for(int i=0;i<=strlen(miwen)-1;i++)
    22     {
    23         if(miwen[i]>='A'&&miwen[i]<='Z')
    24             miwen_x[i]=2;
    25         else
    26             miwen_x[i]=1;
    27         miwen[i]=change(miwen[i]);
    28     }
    29     
    30     char ans[1200];
    31     int j=0;
    32     for(int i=0;i<=strlen(miwen)-1;i++)
    33     {
    34         if(miwen[i]>=key[j])
    35             ans[i]=miwen[i]-key[j]+'a';
    36         else
    37             ans[i]='z'-(key[j]-miwen[i]-1);
    38         if(miwen_x[i]==2)
    39             ans[i]=ans[i]-('a'-'A');
    40         j++;
    41         if(j==len)
    42             j=0;
    43     }
    44     ans[strlen(miwen)]=0;
    45     printf("%s",ans);
    46     
    47             
    48     return 0;
    49 }

     敲黑板结论:读题规划算法比写代码更重要。。。

  • 相关阅读:
    3.nginx反向代理服务器+负载均衡
    2.nginx整合PHP
    nginx-location rewrite
    Nginx(一):安装
    修改host文件原理 localhost,127.0.0.1之间有什么区别
    一个IP绑定多个域名
    私有IP
    转:Hadoop和Spark的异同
    C#中Trim()、TrimStart()、TrimEnd()的用法
    Java操作redis
  • 原文地址:https://www.cnblogs.com/tflsnoi/p/8006708.html
Copyright © 2011-2022 走看看