110304 Crypt Kicker II

来源:互联网 发布:js 设置radio被选中 编辑:程序博客网 时间:2024/04/30 10:26


#include <stdio.h>#include <string.h>#include <iostream>#include <string>#include <vector>using namespace std;class CryptRule{public:CryptRule(){Clear();}bool AddRule(char encryptedLetter, char decryptedLetter){if (m_rules[encryptedLetter - 'a'] == 0){if (m_invertRules[decryptedLetter - 'a'] != 0)return false;m_invertRules[decryptedLetter - 'a'] = encryptedLetter;m_rules[encryptedLetter - 'a'] = decryptedLetter;return true;}return (m_rules[encryptedLetter - 'a'] == decryptedLetter);}void Clear(){for (char i = 'a'; i <= 'z'; ++i){m_rules[i - 'a'] = 0;m_invertRules[i - 'a'] = 0;}}char GetDecryptedChar(char encryptedChar) const{return m_rules[encryptedChar - 'a'];}private:char m_rules['z' - 'a' + 1];char m_invertRules['z' - 'a' + 1];};static const char* const REF_LINE = "the quick brown fox jumps over the lazy dog";static const int SPACE_INFO[] = {3, 9, 15, 19, 25, 30, 34, 39}; // index of space in REF_LINE#define MAX_CHAR_IN_LINE 80 + 2static void GetTestData(vector<string*>& testData){static char buf[MAX_CHAR_IN_LINE];while(true){if (!fgets(buf, MAX_CHAR_IN_LINE, stdin))return;if ((buf[0] == '\0') || (buf[0] == '\n'))return;int nLen = strlen(buf);if (buf[nLen - 1] == '\n')buf[nLen - 1] = '\0';testData.push_back(new string(buf));}}static void ClearTestData(vector<string*>& testData){for (size_t i = 0; i < testData.size(); ++i){delete testData[i];}}static bool CanCreateRule(CryptRule& rule, const char* const refLine, int refLen, const int* spaceInfo, int spaceCnt, const string& data){if (data.length() != refLen)return false;for (int i = 0; i < spaceCnt; ++i){if (data[spaceInfo[i]] != ' ')return false;}int i = 0;char c;while((c = data[i]) != '\0'){if (c != ' '){if (!rule.AddRule(c, refLine[i])){rule.Clear();return false;}}++i;}return true;}static void OutputDecryptData(const CryptRule& rule, const string& data){int i = 0;char c;while( (c = data[i]) != '\0'){if (c != ' ')c = rule.GetDecryptedChar(c);cout << c;++i;}cout << endl;}static void DecryptData(const vector<string*>& testData){CryptRule rule;int refLen = strlen(REF_LINE);bool bSuccess = false;for (size_t i = 0; i < testData.size(); ++i){if (CanCreateRule(rule, REF_LINE, refLen, SPACE_INFO, (sizeof(SPACE_INFO)/sizeof(int)), *(testData[i]))){bSuccess = true;break;}}if (bSuccess){for (size_t i = 0; i < testData.size(); ++i){OutputDecryptData(rule, (*testData[i]));}}elsecout << "No solution." << endl;}static void DoTest(){vector<string*> testData;GetTestData(testData);DecryptData(testData);ClearTestData(testData);}static void TestAll(){int cnt;cin >> cnt;char buf[MAX_CHAR_IN_LINE];fgets(buf, MAX_CHAR_IN_LINE, stdin); // Consume the '\n' after the count of test data groups.fgets(buf, MAX_CHAR_IN_LINE, stdin); // Consume the empty line after the count of test data groups.for (int i = 0; i < cnt; ++i){DoTest();if (i != (cnt - 1))cout << endl;}}int main(int argc, char* argv[]){TestAll();return 0;}