sdut2165 Crack Mathmen (山东省第二届ACM省赛)

本文出自:http://blog.csdn.net/svitter,转载请注明出处。

原题:点击打开链接


晨阳哥一同讨论了一下这个题目= =终于在今晚AC了。

这个题目可以说是RSA加密算法的变种。。

考虑997是素数,那么符合欧拉定理,然后想到费马小定理 m ^ 996 MOD 997 = 1;

因为一般的RSA解密算法都是C^d mod 997 = m 这种形式,苦思冥想了好久解密算法,仍然没有得到解决。

最后终于大彻大悟的明白:

呵呵,你想多了。。这个题目可以用打表过- -

要注意的问题:

1.加密码与原码是要一一对应,在原码中已经标出。

2.计算MOD幂的时候使用二分算法,如果不使用必然超时(n 可以取到  10 ^ 9)。这个算法依据pow算法得出。

/*author : Vit/csdn   
 *from: http://blog.csdn.net/svitter  
 *if you love it, please show the original site*/  


#include <iostream>
#include <stdio.h>
#include <string.h>

using namespace std;

#define lln long long int

char str[1000010];
char key[1001];
lln ch[127];
lln n;
lln ans, tt, temp;

bool get(lln &c)
{
    temp = c, ans = 1, tt = n;
    while(tt)
    {
        if(tt &1)
            ans = (ans * temp) % 997;
        temp = temp * temp % 997;
        tt = tt >> 1;
    }
    if(ch[c] == -1)
        ch[c] = ans;
}

bool init()
{
    lln i;
    memset(ch, -1, sizeof(ch));
    memset(key, '\0', sizeof(key));
    for(i = 32; i < 127; i++)
    {
        if(get(i))
            continue;
        else
            return false;
    }

    for(i = 32; i < 127; i++)
    {
        lln &tmp = ch[i];
        if(key[tmp] == '\0')//检查码值相同的情况
            key[ch[i]] = (char)i;
        else
        {
            return false;
        }
    }
    return true;
}

void ace()
{
    lln c, cur;
    lln length;
    lln i, l;
    char temp[400000];
    bool isstr;
    cin >> c;
    while(c--)
    {
        while(cin >> n)
        {
            memset(str, '\0', sizeof(str));
            scanf("%s", str);
            if(init())
            {
                l = 0;
                isstr = 1;
                //cout << key[590] << endl;
                length = strlen(str);
                for(i = 0; i < length; i += 3)
                {
                    cur = (str[i]-'0') *100 + (str[i+1]-'0') * 10 + str[i+2] - '0';
                    if(key[cur] != '\0')//没有对应的翻译码
                        temp[l++] = key[cur];
                    else
                    {
                        isstr = false;
                        break;
                    }
                }
                if(isstr)
                {
                    for(i = 0; i < l; i++)
                        cout << temp[i];
                    cout << endl;
                }
                else
                {
                    cout << "No Solution" << endl;
                }
            }
            else
            {
                cout << "No Solution" << endl;
            }
        }
    }
}

int main()
{
    ace();
    return 0;
}




你可能感兴趣的:(C++,c,算法,加密,编程语言)