5 条题解

  • 14
    @ 2023-7-12 9:58:21
    #include<bits/stdc++.h>
    using namespace std;
    string k,C;
    char M[130][130]; // 在M[i][i]中,含义为密文i通过密钥j对应的明文
    int main(){
        ios::sync_with_stdio(false); // 输入输出加速
        cin.tie(0);
        cout.tie(0);
        cin>>k>>C;
        // a=97 A=65 Z=90 z=122 这是几个重要英文的ascll值
        for(int i=int('A');i<=int('Z');i++){ // i这里是明文
            for(int j=int('A');j<=int('Z');j++){ // j这里是密钥
                int num=i-int('A')+j; // 由题目中的图片找规律计算对应的密文
                while(num>90)num-=26; // 密文的ascll大于Z的话就要回到A
                M[num][j]=M[num][j+32]=char(i); // 存储密文密钥对应的明文
                // 因为忽略转换过程大小写,所以密钥对应的大写值也要存储
            }
        }
        for(int i=int('a');i<=int('z');i++){
            for(int j=int('a');j<=int('z');j++){
                int num=i-int('a')+j;
                while(num>122)num-=26; // 大于z要回到a
                M[num][j]=M[num][j-32]=char(i);
                // 因为忽略转换过程大小写,所以密钥对应的小写值也要存储
            }
        }
        int cnt=0,lenC=C.size(),lenK=k.size();
        for(int i=0;i<lenC;i++){ // 遍历字符串C
            cout<<M[int(C[i])][int(k[cnt++])]; // 输出密文Ci与密钥ki对应的明文Mi
            if(cnt==lenK)cnt=0; // 密钥长度小于密文长度时重新遍历密钥
        }
        return 0;
    }
    
    • @ 2024-2-27 6:59:57

      w! c!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    • @ 2024-5-28 18:34:36

      666

  • 4
    @ 2023-10-2 12:34:10

    这一题无非是绕来绕去搞得十分复杂,但思路理清晰后还是比较简单的。

    第一种利用设置二维列表。方法复杂度很小,但是你打出这个数组的时间就慢的不得了,这个数组如下

    int jm[45][45]=
            {{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25},
            {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0},
            {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1},
            {3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2},
            {4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3},
            {5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4},
            {6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5},
            {7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6},
            {8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7},
            {9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8},
            {10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9},
            {11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10},
            {12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11},
            {13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12},
            {14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13},
            {15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14},
            {16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15},
            {17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16},
            {18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17},
            {19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18},
            {20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19},
            {21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20},
            {22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21},
            {23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22},
            {24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23},
            {25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24}};
    

    打完这一个数组,在考试的时候已经花了将近七八分钟。所以在考试时这是没有办法的办法。

    但是主函数里的东西明显的就少,注意一下,最好不要经常用万能头文件,这是一个偷懒且不好的习惯,这里需要以下头文件:

    #include <cstring>
    #include <cstdio>
    

    还需要用到头结点:

    #define N 1005
    #define rep(a,b,c) for(int a=b;a<=c;++a)
    

    头结点作用:便于首元结点的处理,最后结点的指针域为空。

    以下是主函数:

    int main()
    {
        scanf("%s",k);
        scanf("%s",s);
        int lk=strlen(k),ls=strlen(s),j=0;
        rep(i,0,ls-1)
        {
            int p=k[j]-'A',g=s[i]-'A',f=0;
            if(p>25) p-=32;
            if(g>25) g-=32,f=1;
            rep(k,0,25)
             if(jm[p][k]==g)
              f?putchar(k+'A'+32):putchar(k+'A');
            j=(j+1)%lk;
        }
        return 0;
    }
    

    这一串主函数很好理解,不多加赘述。

    总体呈现:

    #include <cstring>
    #include <cstdio>
    #define N 1005
    #define rep(a,b,c) for(int a=b;a<=c;++a)
    
    int jm[45][45]=
            {{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25},
            {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0},
            {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1},
            {3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2},
            {4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3},
            {5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4},
            {6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5},
            {7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6},
            {8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7},
            {9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8},
            {10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9},
            {11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10},
            {12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11},
            {13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12},
            {14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13},
            {15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14},
            {16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15},
            {17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16},
            {18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17},
            {19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18},
            {20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19},
            {21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20},
            {22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21},
            {23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22},
            {24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23},
            {25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24}};
    char k[N],s[N];
    int main()
    {
        scanf("%s",k);
        scanf("%s",s);
        int lk=strlen(k),ls=strlen(s),j=0;
        rep(i,0,ls-1)
        {
            int p=k[j]-'A',g=s[i]-'A',f=0;
            if(p>25) p-=32;
            if(g>25) g-=32,f=1;
            rep(k,0,25)
            if(jm[p][k]==g)
              f?putchar(k+'A'+32):putchar(k+'A');
            j=(j+1)%lk;
        }
        return 0;
    }
    

    第二种方法是大家都比较喜欢的方法:遍历密钥与密文,但是注意密钥、密文的大小写。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    
    int main()
    {
        char key[1000],secret[1000];
        int len1,len2;
        int i,j;
     
        gets(key);//输入密钥
        gets(secret);//输入密文
        len1=strlen(key);//求密钥长度
        len2=strlen(secret);//求密文长度
     
        for(i=0; i<len1; i++) //将密钥转换为大写字母
           if((key[i]>='a')&&(key[i]<='z'))
            	key[i]-=32;
     
        for(i=0,j=0; i<len2; i++) //从头开始解密
        {
            if(secret[i]<='Z')//大写的情况
            {
                secret[i]=secret[i]-(key[j]-'A');//按规则解密
                j++;
                if(secret[i]<'A')//若明文小于A
                    secret[i]='Z'-('A'-secret[i])+1;//从字母表倒序转换
            }
            else//小写的情况
            {
                secret[i]=secret[i]-(key[j]-'A');//按规则解密
                j++;
                if(secret[i]<'a')//若明文小于a
                    secret[i]='z'-('a'-secret[i])+1;//从字母表倒序转换
            }
            if(j>len1-1)//若明文长度大于密钥长度,重复使用密钥
                j=0;
        }
        cout<<secret<<endl;
        return 0;
    }
    

    这就是两种写法。

    AC Code1

    #include <cstring>
    #include <cstdio>
    #define N 1005
    #define rep(a,b,c) for(int a=b;a<=c;++a)
    
    int jm[45][45]=
            {{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25},
            {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0},
            {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1},
            {3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2},
            {4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3},
            {5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4},
            {6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5},
            {7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6},
            {8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7},
            {9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8},
            {10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9},
            {11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10},
            {12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11},
            {13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12},
            {14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13},
            {15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14},
            {16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15},
            {17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16},
            {18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17},
            {19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18},
            {20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19},
            {21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20},
            {22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21},
            {23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22},
            {24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23},
            {25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24}};
    char k[N],s[N];
    int main()
    {
        scanf("%s",k);
        scanf("%s",s);
        int lk=strlen(k),ls=strlen(s),j=0;
        rep(i,0,ls-1)
        {
            int p=k[j]-'A',g=s[i]-'A',f=0;
            if(p>25) p-=32;
            if(g>25) g-=32,f=1;
            rep(k,0,25)
             if(jm[p][k]==g)
              f?putchar(k+'A'+32):putchar(k+'A');
            j=(j+1)%lk;
        }
        return 0;
    }
    

    AC Code 2

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    
    int main()
    {
        char key[1000],secret[1000];
        int len1,len2;
        int i,j;
     
        gets(key);//输入密钥
        gets(secret);//输入密文
        len1=strlen(key);//求密钥长度
        len2=strlen(secret);//求密文长度
     
        for(i=0; i<len1; i++) //将密钥转换为大写字母
           if((key[i]>='a')&&(key[i]<='z'))
            	key[i]-=32;
     
        for(i=0,j=0; i<len2; i++) //从头开始解密
        {
            if(secret[i]<='Z')//大写的情况
            {
                secret[i]=secret[i]-(key[j]-'A');//按规则解密
                j++;
                if(secret[i]<'A')//若明文小于A
                    secret[i]='Z'-('A'-secret[i])+1;//从字母表倒序转换
            }
            else//小写的情况
            {
                secret[i]=secret[i]-(key[j]-'A');//按规则解密
                j++;
                if(secret[i]<'a')//若明文小于a
                    secret[i]='z'-('a'-secret[i])+1;//从字母表倒序转换
            }
            if(j>len1-1)//若明文长度大于密钥长度,重复使用密钥
                j=0;
        }
        cout<<secret<<endl;
        return 0;
    }
    
    • 2
      @ 2023-10-28 14:22:38

      首先,我们需要定义一个函数,用于执行Vigenère密码的加密解密操作。然后,我们读取输入数据,并调用这个函数来计算明文。最后,我们将结果输出。

      #include <iostream>
      #include <string>
      #include <map>
      #include <algorithm>
      
      using namespace std;
      
      // 定义一个map,用于存储密钥和对应的字典序
      map<char, int> key_order;
      
      // 初始化密钥和字典序的映射关系
      void init_key_order() {
          for (char c = 'a'; c <= 'z'; ++c) {
              key_order[c] = c - 'a';
          }
          for (char c = 'A'; c <= 'Z'; ++c) {
              key_order[c] = c - 'A' + 26;
          }
      }
      
      // 执行Vigenère密码的加密解密操作
      string vigenère_cipher(const string &m, const string &k) {
          string result;
          int key_len = k.size();
          int plain_len = m.size();
          
          // 初始化密钥和明文的映射关系
          map<int, char> plain_order;
          for (int i = 0; i < plain_len; ++i) {
              char c = m[i];
              int j;
              if (key_order.find(c) != key_order.end()) {
                  j = key_order[c] + key_len * i;
              } else {
                  j = key_order[tolower(c)] + key_len * i;
              }
              plain_order[j] = c;
          }
      
          // 将密文转换为明文
          for (int i = 0; i < key_len; ++i) {
              int j = key_order[k[i]];
              if (plain_order.find(j) != plain_order.end()) {
                  result.push_back(plain_order[j]);
              }
          }
      
          return result;
      }
      
      int main() {
          init_key_order();
          string key, cipher;
          cin >> key >> cipher;
          string plain = vigenère_cipher(cipher, key);
          cout << plain << endl;
          return 0;
      }
      

      这段代码首先定义了一个map,用于存储密钥和对应的字典序。然后定义了一个函数vigenère_cipher,用于执行Vigenère密码的加密解密操作。这个函数首先初始化密钥和明文的映射关系,然后将密文转换为明文。最后,我们读取输入数据,并调用vigenère_cipher函数来计算明文。

      • 1
        @ 2024-2-5 9:21:46

        发现题目中少了个东西,来喽 image

        • 0
          @ 2024-2-5 13:16:07

          1 #include<iostream> #include<cstdio> #include<cstring> using namespace std;

          int main() { char key[1000],secret[1000]; int len1,len2; int i,j;

          gets(key);//输入密钥
          gets(secret);//输入密文
          len1=strlen(key);//求密钥长度
          len2=strlen(secret);//求密文长度
          
          for(i=0; i<len1; i++) //将密钥转换为大写字母
             if((key[i]>='a')&&(key[i]<='z'))
              	key[i]-=32;
          
          for(i=0,j=0; i<len2; i++) //从头开始解密
          {
              if(secret[i]<='Z')//大写的情况
              {
                  secret[i]=secret[i]-(key[j]-'A');//按规则解密
                  j++;
                  if(secret[i]<'A')//若明文小于A
                      secret[i]='Z'-('A'-secret[i])+1;//从字母表倒序转换
              }
              else//小写的情况
              {
                  secret[i]=secret[i]-(key[j]-'A');//按规则解密
                  j++;
                  if(secret[i]<'a')//若明文小于a
                      secret[i]='z'-('a'-secret[i])+1;//从字母表倒序转换
              }
              if(j>len1-1)//若明文长度大于密钥长度,重复使用密钥
                  j=0;
          }
          cout<<secret<<endl;
          return 0;
          

          } 2 #include<bits/stdc++.h> using namespace std; string k,C; char M[130][130]; // 在M[i][i]中,含义为密文i通过密钥j对应的明文 int main(){ ios::sync_with_stdio(false); // 输入输出加速 cin.tie(0); cout.tie(0); cin>>k>>C; // a=97 A=65 Z=90 z=122 这是几个重要英文的ascll值 for(int i=int('A');i<=int('Z');i++){ // i这里是明文 for(int j=int('A');j<=int('Z');j++){ // j这里是密钥 int num=i-int('A')+j; // 由题目中的图片找规律计算对应的密文 while(num>90)num-=26; // 密文的ascll大于Z的话就要回到A M[num][j]=M[num][j+32]=char(i); // 存储密文密钥对应的明文 // 因为忽略转换过程大小写,所以密钥对应的大写值也要存储 } } for(int i=int('a');i<=int('z');i++){ for(int j=int('a');j<=int('z');j++){ int num=i-int('a')+j; while(num>122)num-=26; // 大于z要回到a M[num][j]=M[num][j-32]=char(i); // 因为忽略转换过程大小写,所以密钥对应的小写值也要存储 } } int cnt=0,lenC=C.size(),lenK=k.size(); for(int i=0;i<lenC;i++){ // 遍历字符串C cout<<M[int(C[i])][int(k[cnt++])]; // 输出密文Ci与密钥ki对应的明文Mi if(cnt==lenK)cnt=0; // 密钥长度小于密文长度时重新遍历密钥 } return 0; } 3 #include <cstring> #include <cstdio> #define N 1005 #define rep(a,b,c) for(int a=b;a<=c;++a)

          int jm[45][45]= {{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25}, {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0}, {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1}, {3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2}, {4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3}, {5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4}, {6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5}, {7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6}, {8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7}, {9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8}, {10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9}, {11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10}, {12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11}, {13,14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12}, {14,15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13}, {15,16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14}, {16,17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}, {17,18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}, {18,19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17}, {19,20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18}, {20,21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19}, {21,22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}, {22,23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21}, {23,24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22}, {24,25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23}, {25,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24}}; char k[N],s[N]; int main() { scanf("%s",k); scanf("%s",s); int lk=strlen(k),ls=strlen(s),j=0; rep(i,0,ls-1) { int p=k[j]-'A',g=s[i]-'A',f=0; if(p>25) p-=32; if(g>25) g-=32,f=1; rep(k,0,25) if(jm[p][k]==g) f?putchar(k+'A'+32):putchar(k+'A'); j=(j+1)%lk; } return 0; } 4 #include <iostream> #include <string> #include <map> #include <algorithm>

          using namespace std;

          // 定义一个map,用于存储密钥和对应的字典序 map<char, int> key_order;

          // 初始化密钥和字典序的映射关系 void init_key_order() { for (char c = 'a'; c <= 'z'; ++c) { key_order[c] = c - 'a'; } for (char c = 'A'; c <= 'Z'; ++c) { key_order[c] = c - 'A' + 26; } }

          // 执行Vigenère密码的加密解密操作 string vigenère_cipher(const string &m, const string &k) { string result; int key_len = k.size(); int plain_len = m.size();

          // 初始化密钥和明文的映射关系
          map<int, char> plain_order;
          for (int i = 0; i < plain_len; ++i) {
              char c = m[i];
              int j;
              if (key_order.find(c) != key_order.end()) {
                  j = key_order[c] + key_len * i;
              } else {
                  j = key_order[tolower(c)] + key_len * i;
              }
              plain_order[j] = c;
          }
          
          // 将密文转换为明文
          for (int i = 0; i < key_len; ++i) {
              int j = key_order[k[i]];
              if (plain_order.find(j) != plain_order.end()) {
                  result.push_back(plain_order[j]);
              }
          }
          
          return result;
          

          }

          int main() { init_key_order(); string key, cipher; cin >> key >> cipher; string plain = vigenère_cipher(cipher, key); cout << plain << endl; return 0; }

          • 1

          信息

          ID
          2057
          时间
          1000ms
          内存
          128MiB
          难度
          3
          标签
          (无)
          递交数
          267
          已通过
          135
          上传者