题解:P1079 [NOIP2012 提高组] Vigenère 密码

· · 题解

P1079 题解

本蒟蒻的第一篇题解。

大体思路:

先定义一个密钥 k 的指针变量 q,表示密文要减去 k 的第几位。

定义指针变量 i,表示密文 M 的第几位。从 0|M|(注:|M| 表示 M 的长度。)枚举 i,判断 M_i 的大小写,再判断密钥 k_q 的大小写:

在每一次遍历中,M_i 减去 1,且:

遍历完之后,变量 q 增加 1,如果 q=|k|,则 q \gets 0

这样就可以把密文转化为明文。

示范代码:

#include<bits/stdc++.h>

using namespace std;

string k,s;//定义密钥字符串k和密文字符串s

int main() {

    cin>>k>>s;//输入k和s

    int q=0;//定义指针变量q

    for(int i=0;i<s.size();i++){//遍历密文字符串

        if(s[i]>='A'&&s[i]<='Z'){//判断密文大小写

            int h=k[q]>='A'&&k[q]<='Z'?k[q]-'A':k[q]-'a';//判断密钥大小写,并求出遍历次数

            for(int j=0;j<h;j++){//遍历还原

                s[i]--;

                if(s[i]<'A'){//特判,使变化符合规则

                    s[i]='Z';

                }

            }

        }

        if(s[i]>='a'&&s[i]<='z'){//与上面思路相同

            int h=k[q]>='A'&&k[q]<='Z'?k[q]-'A':k[q]-'a';

            for(int j=0;j<h;j++){

                s[i]--;

                if(s[i]<'a'){

                    s[i]='z';

                }

            }

        }

        q++;//指针指向下一位

        if(q==k.size()){//特判,使指针回到开头

            q=0;

        }

    }

    cout<<s;//输出

    return 0;

}