Crack Mathmen
Time Limit: 1000MS Memory limit: 65536K
题目描述
For example, if they choose n = 2 and the message is "World" (without quotation marks), they encode the message like this:
1. the first character is 'W', and it's ASCII code is 87. Then f(′W′) = 87^2 mod 997 = 590.
2. the second character is 'o', and it's ASCII code is 111. Then f(′o′) = 111^2 mod 997 = 357.
3. the third character is 'r', and it's ASCII code is 114. Then f(′r′) = 114^2 mod 997 = 35. Since 10 <= f(′r′) < 100, they add a 0 in front and make it 035.
4. the forth character is 'l', and it's ASCII code is 108. Then f(′l′) = 108^2 mod 997 = 697.
5. the fifth character is 'd', and it's ASCII code is 100. Then f(′d′) = 100^2 mod 997 = 30. Since 10 <= f(′d′) < 100, they add a 0 in front and make it 030.
6. Hence, the encrypted message is "590357035697030".
One day, an encrypted message a mathman sent was intercepted by the human being. As the cleverest one, could you find out what the plain text (i.e., the message before encryption) was?
输入
输出
示例输入
3 2 590357035697030 0 001001001001001 1000000000 001001001001001
示例输出
World No Solution No Solution
分析:题意是,对字母和数字进行编码,每个字母或数字的编码都是三位,编码规则为该字符的ASCII值的n次方mod 997。并保证对每个字符(只包括字母和数字)的编码存在且唯一,若译码结果不是字符或数字则输出No Solution
用快速幂求出相应的编码,再用编码做为数字下表存字符,例如ch[ 590 ]='W';
代码如下:
#include <stdio.h>
#include <string.h>
long long powerMod(long long a,long long b,long long c)
{
long long ans=1;
a=a%c;
while(b>0)
{
if(b%2==1)
ans=(ans*a)%c;
b=b/2;
a=(a*a)%c;
}
return ans;
}
int main()
{
int i,j;
int T;
int b,c;
long long n;
char a[1005],str[1000005];
scanf("%d",&T);
while(T--)
{
int peace=0;
scanf("%I64d%*c",&n);
memset(a,' ',sizeof(a));
for(i=0;i<26;i++)
{
long long ans=powerMod('a'+i,n,997);<span style="white-space:pre"> </span>//快速幂小写字母编码
if(a[ans]==' ')<span style="white-space:pre"> </span>//保证编码不重复
a[ans]='a'+i;
else
{
peace=1;
break;
}
}
for(i=0;i<26 && !peace;i++)
{
long long ans=powerMod('A'+i,n,997);<span style="white-space:pre"> </span>//快速幂大写字母编码
if(a[ans]==' ')
a[ans]='A'+i;
else
{
peace=1;
break;
}
}
for(i=0;i<10 && !peace;i++)
{
long long ans=powerMod('0'+i,n,997);<span style="white-space:pre"> </span>//快速幂数字编码
if(a[ans]==' ')
a[ans]='0'+i;
else
{
peace=1;
break;
}
}
scanf("%s",str);
if(!peace)
{
int len=strlen(str);
for(i=0;i<len;i+=3)
{
int ans;
ans=(str[i]-'0')*100+(str[i+1]-'0')*10+(str[i+2]-'0');
if(a[ans]!=' ')
printf("%c",a[ans]);
else
{
printf("No Solution");
break;
}
}
putchar('\n');
}
else
{
printf("No Solution\n");
}
}
return 0;
}