原题链接

题目大意:按照规则解码。26个字母分成三组,每一组按照顺时针移位编码。现在已知移动的位数,要求解码。

解法:以前看过一本古典密码学的书,百度贴吧密码吧也有很多经典的加密方法,想什么凯撒移位、弗吉尼亚编码等等。古典密码学比现代密码学有趣多了。这道题可以开三个队列,先把字符串压入对应的队列,然后调整顺序,再合成输出。不难,稍烦。

 

参考代码:

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

int main(){
	int k1,k2,k3,i,len,pos[100];
	char str[100],c;
	queue<char> s1;
	queue<char> s2;
	queue<char> s3;

	while(cin>>k1>>k2>>k3){
		if(k1==0&&k2==0&&k3==0)break;
		scanf("%s",&str);
		while(!s1.empty())s1.pop();		//empty queues
		while(!s2.empty())s2.pop();
		while(!s3.empty())s3.pop();
		len=strlen(str);
		for(i=0;i<len;i++){
			if(str[i]<='i'&&str[i]>='a'){
				s1.push(str[i]);
				pos[i]=1;
			}
			else if(str[i]<='r'&&str[i]>='j'){
				s2.push(str[i]);
				pos[i]=2;
			}
			else{
				s3.push(str[i]);
				pos[i]=3;
			}
		}
		if(!s1.empty())k1=k1%(s1.size());	// if s1 is empyt, k1%(s1.seze()) will cause floating point error 
		if(!s2.empty())k2=k2%(s2.size());
		if(!s3.empty())k3=k3%(s3.size());
		while(k1<s1.size()){
			c=s1.front();
			s1.pop();
			s1.push(c);
			k1++;
		}
		while(k2<s2.size()){
			c=s2.front();
			s2.pop();
			s2.push(c);
			k2++;
		}
		while(k3<s3.size()){
			c=s3.front();
			s3.pop();
			s3.push(c);
			k3++;
		}
		for(i=0;i<len;i++){
			switch(pos[i]){
			case 1:
				cout<<s1.front();
				s1.pop();
				break;
			case 2:
				cout<<s2.front();
				s2.pop();
				break;
			case 3:
				cout<<s3.front();
				s3.pop();
				break;
			}
		}
		cout<<endl;
	}
		


	return 0;
}