noip 2012 D1T1 luogu P1079 Vigenère 密码

版权声明:thanks for your copy! https://blog.csdn.net/weixin_43907802/article/details/88910217

在这里插入图片描述
在这里插入图片描述

analysis

对于这个题打表的同学,我表示敬佩
题意很简单,就是给一个加密后的字符串,一个转换的密匙,要求的是原来的字符串

其实不需要打表,因为通过仔细观察题中所给的表,不难发现明文的ascll码(设为a),密文的ascll码(b),密匙的ascll码(c)之间有一定数量关系:

	//ascll:a=>97 A=>65 z=>122 Z=>90
	if(b[i]-a[i%lena]>=0)res[i]='a'+b[i]-a[i%lena]; //lena是密匙的长度      
	else res[i]=97+(25-(a[i%lena]-1-b[i]));

可以直接依据这个式子来转换,就不需要打700多行的表了

code

#include<bits/stdc++.h>
using namespace std;
#define loop(i,start,end) for(register int i=start;i<=end;++i)
#define anti_loop(i,start,end) for(register int i=start;i>=end;--i)
#define max(a,b) ((a>b)?a:b)
#define min(a,b) ((a<b)?a:b)
#define ll long long
#define clean(arry,num) memset(arry,num,sizeof(arry))
char a[200];
char b[5000];
char res[5000];
bool big[5000];
template<typename T>void read(T &x)
{
	x=0;char r=getchar();T neg=1;
	while(r>'9'||r<'0'){if(r=='-')neg=-1;r=getchar();}
	while(r<='9'&&r>='0'){x=(x<<1)+(x<<3)+r-'0';r=getchar();}
	x*=neg;
}
int main()
{
	//a=>97 A=>65 z=>122 Z=>90
	scanf("%s %s",a,b);
	clean(big,false);
	int lena=strlen(a);int lenb=strlen(b); 
	loop(i,0,lena-1)if(a[i]>=65&&a[i]<=90)a[i]=97+a[i]-'A';
	loop(i,0,lenb-1)if(b[i]>=65&&b[i]<=90)big[i]=true,b[i]=97+b[i]-'A';//大化小
	loop(i,0,lenb-1)
	{
		if(b[i]-a[i%lena]>=0)res[i]='a'+b[i]-a[i%lena];
		else res[i]=97+(25-(a[i%lena]-1-b[i]));
	}
	loop(i,0,lenb-1)
	{
		if(big[i])printf("%c",res[i]-'a'+65);
		else printf("%c",res[i]);
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43907802/article/details/88910217