您的位置:首页 > 其它

ZOJ1009

2016-01-24 17:12 246 查看
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1009

所给的转子并不是能把某个字母换成另一个字母,而是给出了一个转化关系,让所对应的字母向后或向前移动几个位置得到的字母就是密文。

一开始是想倒着推导出明文,可是发现根本无法推导,因为一个明文向前或向后移动几个位置得到一个密文后,在不知道怎么移动的情况下,是不会得到明文的。(这是当时的想法,后来看了题解才知道可以推,但是我实在不想看了)

倒推不行的话,就正着推,对于当前转子的状态,每个明文只会对应一个密文,因为m<=26,所以只要一个个尝试就可以了。

(因为一个小失误,wa了好多次)

#include<iostream>
#include<cstdio>
#include<cstring>

using namespace std;

int main()
{
int m;
int rotor[3][30];
int tmprotor[3][30];
char cipher[1000];
int number = 0;

while (cin>>m && m != 0)
{
number++;
if (number != 1)
cout<<endl;
cout<<"Enigma "<<number<<":"<<endl;
memset(rotor,0,sizeof(rotor));

getchar();
for (int i=0; i<m ;i++)
{
char ch = getchar();
rotor[0][i] = ch - 'A' - i;
tmprotor[0][i] = rotor[0][i];
}
getchar();
for (int i=0; i<m ;i++)
{
char ch = getchar();
rotor[1][i] = ch - 'A' - i;
tmprotor[1][i] = rotor[1][i];
}
getchar();
for (int i=0; i<m ;i++)
{
char ch = getchar();
rotor[2][i] = ch - 'A' - i;
tmprotor[2][i] = rotor[2][i];
}

int time;
cin>>time;
for (int j=0; j<time; j++)
{
scanf("%s",cipher);
int len = strlen(cipher);
for (int i=0; i<len ;i++)
{
int tmp = cipher[i] - 'A';
int k;
for (k=0; k<m; k++)
{
int now = k;
now += rotor[0][now];
now %= m; if (now < 0) now += m;

now += rotor[1][now];
now %= m; if (now < 0) now += m;

now += rotor[2][now];  //曾经把rotor[2][now]写成了rotor[1][now],就是这个失误一直没过<img alt="大哭" src="http://static.blog.csdn.net/xheditor/xheditor_emot/default/wail.gif" />
now %= m; if (now < 0) now += m;

if (now == tmp)
break;
}
printf("%c",'a'+k);

for (int k=m; k>=1; k--)
rotor[0][k] = rotor[0][k-1];
rotor[0][0] = rotor[0][m];
if ((i+1) % m == 0)
{
for (int k=m; k>=1; k--)
rotor[1][k] = rotor[1][k-1];
rotor[1][0] = rotor[1][m];
if ((i+1) % (m*m) == 0)
{
for (int k=m; k>=1; k--)
rotor[2][k] = rotor[2][k-1];
rotor[2][0] = rotor[2][m];
}
}
}
cout<<endl;
for (int i=0; i<3; i++)
for (int k=0; k<m; k++) rotor[i][k] = tmprotor[i][k];
}
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: