NOIP2012 Day1 vigenere密码

【问题描述】

有一位法国外交家发明了一种神奇的算法明文是M,密钥是k,密文是C。加密规则如下:

c[i]=m[i]@k[i]

密钥
加密注意点;
1、加密时忽略明文和密钥的大小写,并在密文中保持明文的大小写
2、当明文M的长度大于密钥K的长度时,K可以被循环使用。
例如,明文 M=HelloworldM=Helloworld ,密钥 k=abck=abc 时,密文 C=HfnlpyosndC=Hfnlpyosnd 。

【输入输出格式】

共两行,第一行为密钥K,长度不超过100;第二行为密文M,长度不超过1000.

【输出样例】

CompleteVictory
Yvqgpxaimmklongnzfwpvxmniytm

【输出样例】

Wherethereisawillthereisaway


【分析】

利用密文还原明文
先把密钥转换可以加减的[0,25]的数字,如下依次操作每个密文:
把密文也转化成[0,25]的数字,并用变量tmp保留其大小写。
把密文减密钥,如果结果小于0,则再加上26
最后再加上tmp转换为明文

如下附上代码一份:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=1010;
char m[maxn],k[maxn];
int lm,lk,key[maxn];
int main()
{
    freopen("vigenere.in","r",stdin);
    freopen("vigenere.out","w",stdout);
    scanf("%s%s",k,m);
    lm=strlen(m),lk=strlen(k);
    for(int i=0;i<lk;i++)
        if(k[i]>='a'&&k[i]<='z') key[i]=k[i]-'a';
        else key[i]=k[i]-'A';
    int j=0;
    for(int i=0;i<lm;i++)
    {
        char tmp;
        if(m[i]>='a'&&m[i]<='z') tmp='a',m[i]-='a';
        else tmp='A',m[i]-='A';//用tmp储存大小写
        m[i]-=key[j];
        if(m[i]<0) m[i]+=26;
        m[i]+=tmp;//再次转换成明文
        j++;//密钥可能会被重复使用
        if(j>=lk) j-=lk;
    }
    for(int i=0;i<lm;i++)
        printf("%c",m[i]);
    return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值