山东省第二届ACM大学生程序设计竞赛 Crack Mathmen
题意:
有一个解码规则:
字母或者数字的ASCII码,然后平方,%997,得出一个数字,如果这个数字不够三位数的话,在前面加上0凑够它,从而得到了一个数字。
现在我们要做的就是把他给出的一串数字解码,解出他的信息。
先把数字和字母对应的数字解出来,如果有相同的话,对号入座。
AC代码:
#include <iostream> #include <cstdio> #include <cstring> #include <map> #define mod 997 using namespace std; int t, n; int a[1000001], cnt; char str[1000010]; int solve(int a, int n) { if(n == 0) return 1; int x = solve(a, n / 2); long long ans = (long long)x * x % mod; if(n % 2 == 1) ans = ans * a % mod; return (int)ans; } int main() { map<int, char>m; map<int, int>flag; scanf("%d", &t); while(t--) { m.clear(); flag.clear(); cnt = 0; scanf("%d", &n); scanf("%s", str); int len = strlen(str); if(len % 3 != 0) { printf("No Solution\n"); continue; } for(int i = 0; i < len ; i+=3) { int tmp = 0; tmp = tmp * 10 + str[i] - '0'; tmp = tmp * 10 + str[i + 1] - '0'; tmp = tmp * 10 + str[i + 2] - '0'; a[cnt++] = tmp; } for(int i = 65; i <= 90; i++) { int tmp = solve(i, n); m[tmp] = (char)i; flag[tmp]++; } for(int i = 48; i <= 57; i++) { int tmp = solve(i, n); m[tmp] = (char)i; flag[tmp]++; } for(int i = 97; i <= 122; i++) { int tmp = solve(i, n); m[tmp] = (char)i; flag[tmp]++; } bool mark = 1; for(int i = 0; i < cnt; i++) { if(flag[a[i]] != 1) { mark = 0; break; } else { str[i] = m[a[i]]; } } str[cnt] = '\0'; if(!mark) printf("No Solution\n"); else printf("%s\n", str); } return 0; } /************************************** Problem id : SDUT OJ E User name : xam140325乔璐 Result : Accepted Take Memory : 2568K Take Time : 40MS Submit Time : 2016-05-02 16:41:19 **************************************/