ZOJ1009

题目链接: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;
}


你可能感兴趣的:(ZOJ1009)