~cpp // no850 - Crypt Kicker2 #include <iostream> #include <cstring> #include <string> #include <cctype> using namespace std; /* 평문공격법 "the quick brown fox jumps over the lazy dog" 43자 빈도수 4, 3, 2, 2, 2, 2, 1, ... */ const int MAX_LEN = 81; const int PROPER_LEN = 43; bool input(string & s, char * rul); bool isreplace(char * str); void findRule(char * str, char * rul); void decoding(string & s, char * rul); inline void output(string & s) { cout << s; } int main() { int nCase; cin >> nCase; cin.get(), cin.get(); char rule[26]; int i; for (i=0; i<nCase; i++) { string s; if (input(s, rule)) { decoding(s, rule); output(s); } else cout << "No solution.\n"; if (i != nCase-1) cout << endl; } return 0; } bool input(string & s, char * rul) { char str[MAX_LEN]; bool serch = false; while (cin.peek() != '\n' && cin.peek() != EOF) { cin.getline(str, MAX_LEN, '\n'); if (isreplace(str)) { serch = true; findRule(str, rul); } s += str; s += '\n'; } cin.get(); if (serch) return true; return false; } bool isreplace(char * str) { int len = strlen(str); if (len != PROPER_LEN) // 1차 - 길이 비교 return false; // 여백 위치 비교 else if (!(str[3] == ' ' && str[9] == ' ' && str[15] == ' ' && str[19] == ' ' && str[25] == ' ' && str[30] == ' ' && str[34] == ' ' && str[39] == ' ')) return false; int i; int count2, count3, count4; count2 = count3 = count4 = 0; int alpa[26] = {0,}; for (i=0; i<len; i++) { if (isalpha(str[i])) alpa[str[i]-97]++; } for (i=0; i<26; i++) { if (alpa[i] == 2) count2++; else if (alpa[i] == 3) count3++; else if (alpa[i] == 4) count4++; } if (!(count2 == 4 && count3 == 1 && count4 == 1)) // 알파벳 빈도수 조사 return false; return true; } void findRule(char * str, char * rul) { char strOrin[] = "the quick brown fox jumps over the lazy dog"; int i; for (i=0; i<PROPER_LEN; i++) { if (isalpha(str[i])) { rul[str[i]-97] = strOrin[i]; } } } void decoding(string & s, char * rul) { int i; int len = s.size(); for (i=0; i<len; i++) { if (isalpha(s[i])) { s[i] = rul[s[i]-97]; } } }