Cryptcowgraphy [USACO]
2013-03-14 11:34
357 查看
擦,公司上不了USACO了,怀疑公司用了一个牛X的防火墙,通过机器学习把我给禁掉了,实在恶心。我还以为USACO挂掉了,还好今天灵机一动,用“在线代理”这个有点sexy的网站可以突破天际。
这道题太恶心。。。我开始用的set<string> 妥妥的,bad_alloc啥的,可能是内存不足吧(USACO有16M内存的限制??),后来自己实现了个hash表,自己来,擦的,用了16228KB,又bad_alloc了,折腾许久,无解。百度了一下,发现大家都不解决hash conflict,居然也过了...唉,就这样吧,我用的BKDR_Hash,因为这个hash 简单,而且效果很好,有本书上讲的。
原题如下:
Cryptcowgraphy
Brian Dean
The cows of Farmer Brown and Farmer John are planning a coordinated escape from their respective farms and have devised a method of encryption to protect their written communications.
Specifically, if one cow has a message, say, "International Olympiad in Informatics", it is altered by inserting the letters C, O, and W, in random location in the message, such that C appears before O, which appears before W. Then the cows take the part of the message between C and O, and the part between O and W, and swap them. Here are two examples:
To make matters more difficult, the cows can apply their encryption scheme several times, by again encrypting the string that results from the previous encryption. One night, Farmer John's cows receive such a multiply-encrypted message. Write a program to compute whether or not the non-encrypted original message could have been the string:
----------------------------------------------------------------------------------分割线---------------------------------------------------------------
以下为测试数据:
Here are the test data inputs:
这道题太恶心。。。我开始用的set<string> 妥妥的,bad_alloc啥的,可能是内存不足吧(USACO有16M内存的限制??),后来自己实现了个hash表,自己来,擦的,用了16228KB,又bad_alloc了,折腾许久,无解。百度了一下,发现大家都不解决hash conflict,居然也过了...唉,就这样吧,我用的BKDR_Hash,因为这个hash 简单,而且效果很好,有本书上讲的。
/* ID: zhangyc1 LANG: C++ TASK: cryptcow */ #include <fstream> #include <iostream> #include <cstdlib> #include <cstring> #include <string> using namespace std; // Begin the Escape execution at the Break of Dawn ofstream fileout("cryptcow.out"); string strNormal = "Begin the Escape execution at the Break of Dawn"; string strInput; int strInputLen = 0; int arrChNum[2][53]; bool bEable = false; int nRs = 0; const int HashSize = 362881; /* struct SHash { char* str; SHash* pNext; SHash():str(NULL), pNext(NULL){} }; */ //SHash* hashTable[HashSize]; bool hashTable[HashSize]; unsigned int BKDR_Hash(const string& ss) { unsigned int nSeed = 131; unsigned int nHash = 0; int nLen = ss.length(); for (int i = 0; i < nLen; i++) nHash = nHash * nSeed + (unsigned int)ss[i]; return nHash % HashSize; } bool prepairData() { memset(arrChNum, 0, sizeof(arrChNum)); memset(hashTable, 0, sizeof(hashTable)); ifstream filein("cryptcow.in"); getline(filein, strInput); filein.close(); strInputLen = strInput.size(); int nNumC = 0, nNumO = 0, nNumW = 0, nNumSp = 0; int arrPosC[9], arrPosO[9], arrPosW[9], arrPosSp[30]; for (int i = 0; i < strInputLen; i++) { if (strInput[i] == 'C') { arrPosC[nNumC++] = i; } else if (strInput[i] == 'O') { arrPosC[nNumO++] = i; } else if (strInput[i] == 'W') { arrPosW[nNumW++] = i; } else { if (strInput[i] >= 'A' && strInput[i] <= 'Z') arrChNum[1][strInput[i] - 'A']++; else if (strInput[i] >= 'a' && strInput[i] <= 'z') arrChNum[1][strInput[i] - 'a' + 26]++; else arrChNum[1][52]++; } if (nNumC > 9 || nNumO > 9 || nNumW > 9) { return false; } } // C O W 个数相等 if (nNumC != nNumO || nNumO != nNumW) return false; for (int i = 0; i < 47; i++) { if (strNormal[i] >= 'A' && strNormal[i] <= 'Z') arrChNum[0][strNormal[i] - 'A']++; else if(strNormal[i] >= 'a' && strNormal[i] <= 'z') arrChNum[0][strNormal[i] - 'a' + 26]++; else arrChNum[0][52]++; } // 各字符个数相等 for (int i = 0; i < 53; i++) { if (arrChNum[0][i] != arrChNum[1][i]) return false; } nRs = nNumC; return true; } bool dfs(string ss) { int nNumC = 0, nNumO = 0, nNumW = 0, nNumSp = 0; int arrPosC[9], arrPosO[9], arrPosW[9], arrPosSp[30]; int nStrLen = ss.length(); if (nStrLen == 47) return ss.compare(strNormal) == 0; for (int i = 0; i < nStrLen; i++) { if (ss[i] == 'C') { arrPosC[nNumC++] = i; arrPosSp[nNumSp++] = i; } else if (ss[i] == 'O') { arrPosO[nNumO++] = i; arrPosSp[nNumSp++] = i; } else if (ss[i] == 'W') { arrPosW[nNumW++] = i; arrPosSp[nNumSp++] = i; } } if (arrPosSp[0] != arrPosC[0] || arrPosSp[nNumSp - 1] != arrPosW[nNumW - 1]) return false; string strSub = ""; if (arrPosSp[0] != 0) { strSub = ss.substr(0, arrPosSp[0]); // 必须为目标串的开头 if (strSub.compare(strNormal.substr(0, arrPosSp[0])) != 0) return false; } if (arrPosSp[nNumSp - 1] != nStrLen - 1) { strSub = ss.substr(arrPosSp[nNumSp - 1] + 1, nStrLen - arrPosSp[nNumSp - 1] - 1); // 必须为目标串的结尾 if (strSub.compare(strNormal.substr(47 - nStrLen + arrPosSp[nNumSp - 1] + 1, nStrLen - arrPosSp[nNumSp - 1] - 1)) != 0) return false; } for (int i = 0; i <= nNumSp - 2; i++) { strSub = ss.substr(arrPosSp[i] + 1, arrPosSp[i + 1] - arrPosSp[i] - 1); if (strSub.length() == 0) continue; else if (strSub.length() == 47) return strSub.compare(strNormal) == 0; else { unsigned int nHash = BKDR_Hash(strSub); if (strNormal.find(strSub) == string::npos) return false; } } for (int i = 0; i < nNumC; i++) for (int j = 0; j < nNumO; j++) { if (arrPosO[j] < arrPosC[i]) continue; for (int k = nNumW - 1; k >= 0; k--) { if (arrPosW[k] < arrPosO[j]) continue; string s0 = ss.substr(0, arrPosC[i]); string s1 = ss.substr(arrPosC[i] + 1, arrPosO[j] - arrPosC[i] - 1); string s2 = ss.substr(arrPosO[j] + 1, arrPosW[k] - arrPosO[j] - 1); string s3 = ss.substr(arrPosW[k] + 1, nStrLen - arrPosW[k] - 1); string newSS = s0 + s2 + s1 + s3; bool bSkip = false; for (int i = 0; i < newSS.length(); i++) { if (newSS[i] == 'C') break; else if (newSS[i] == 'O' || newSS[i] == 'W') { bSkip = true; break; } } if (bSkip) continue; for (int i = newSS.length() - 1; i >= 0; i--) { if (newSS[i] == 'W') break; else if (newSS[i] == 'O' || newSS[i] == 'C') { bSkip = true; break; } } if (bSkip) continue; unsigned int nHash = BKDR_Hash(newSS); /* SHash* pHash = hashTable[nHash]; SHash* pPreHash = NULL; while (pHash && pHash->str) { if (strcmp(pHash->str, newSS.c_str()) == 0) { bSkip = true; break; } pPreHash = pHash; pHash = pHash->pNext; } if (bSkip) continue; */ if (!hashTable[nHash]) { if (dfs(newSS)) return true; else hashTable[nHash] = true; } /* if (dfs(newSS)) return true; pHash = new SHash(); pHash->str = new char[newSS.length() + 1]; strcpy(pHash->str, newSS.c_str()); if (pPreHash) pPreHash->pNext = pHash; */ } } return false; } void process() { bEable = dfs(strInput); if (!bEable) nRs = 0; } int main(){ if(prepairData()) { process(); } fileout << bEable << " " << nRs << endl; fileout.close(); return 0; }
原题如下:
Cryptcowgraphy
Brian Dean
The cows of Farmer Brown and Farmer John are planning a coordinated escape from their respective farms and have devised a method of encryption to protect their written communications.
Specifically, if one cow has a message, say, "International Olympiad in Informatics", it is altered by inserting the letters C, O, and W, in random location in the message, such that C appears before O, which appears before W. Then the cows take the part of the message between C and O, and the part between O and W, and swap them. Here are two examples:
International Olympiad in Informatics -> CnOIWternational Olympiad in Informatics International Olympiad in Informatics -> International Cin InformaticsOOlympiad W
To make matters more difficult, the cows can apply their encryption scheme several times, by again encrypting the string that results from the previous encryption. One night, Farmer John's cows receive such a multiply-encrypted message. Write a program to compute whether or not the non-encrypted original message could have been the string:
Begin the Escape execution at the Break of Dawn
PROGRAM NAME: cryptcow
INPUT FORMAT
A single line (with both upper and lower case) with no more than 75 characters that represents the encrypted message.SAMPLE INPUT (file cryptcow.in)
Begin the EscCution at the BreOape execWak of Dawn
OUTPUT FORMAT
Two integers on a single line. The first integer is 1 if the message decodes as an escape message; 0 otherwise. The second integer specifies the number of encryptions that were applied (or 0 if the first integer was 0).SAMPLE OUTPUT (file cryptcow.out)
1 1
----------------------------------------------------------------------------------分割线---------------------------------------------------------------
以下为测试数据:
Here are the test data inputs:
------- test 1 ---- Begin the Escape execution at the Break of Dawn ------- test 2 ---- CBegin the EscCution at the BreOape execWak of OWDawn ------- test 3 ---- Begin the EscCutino at the BreOape execWak of Dawn ------- test 4 ---- Begin the EscCCCCCCution at the BreOOOOOOape execWWWWWWak of Dawn ------- test 5 ---- CaOBegin the EscWpe CnCak OexeOt the BWcutioWofO aCreW Dawn ------- test 6 ---- BCC execuO the EsCinCaWCCreaOpWtiOn at OCDOcOWaOegCeWtheOW BWoWk of Wwn ------- test 7 ---- BegiCoWCWDOk oCthe EscOWaCn Oe Of On WexecutChe BreOOCat tWiWapCWawn ------- test 8 ---- BeCOgC CC execuOf DOBCiCCrWaOOt theCOCeak oWWin Oon aWtheOOW EscapeWtWWWwn ------- test 9 ---- CChCC Oe BWOWEscapCreOeOegin tWOe WatWaOe OBCexCOhWC of O tCWcutionWkWDawn ------- test 10 ---- CCC COhe BWOWEscapCreOeOegin tWOe WatWaOe OBCexCOhWC of O tCWcutionWkWDawn
相关文章推荐
- usaco6.3.2 Cryptcowgraphy
- usaco 4.1 Cryptcowgraphy
- USACO4.1.4 Cryptcowgraphy
- usaco4.1.4 Cryptcowgraphy
- usaco 4.1 Cryptcowgraphy(DFS+hash+剪枝)
- USACO 4.1 Cryptcowgraphy(DFS)
- [USACO 6.3.2] Cryptcowgraphy
- USACO 6.3.2 Cryptcowgraphy 剪枝
- Cryptcowgraphy USACO 4.1(dfs搜索+剪枝)
- usaco 4.1 Cryptcowgraphy 剪枝
- USACO Section 4.1 Cryptcowgraphy - BT的DFS剪枝..
- USACO 6.3 Cryptcowgraphy
- Cryptcowgraphy[需重做]
- 【CodeVS 2083】Cryptcowgraphy 解密牛语
- 【CodeVS 2083】Cryptcowgraphy 解密牛语
- USACO6.3.2 Cryptcowgraph(cryptcow)
- [USACO4.1.4 Cryptcowgraphy]
- bzoj1631: [Usaco2007 Feb]Cow Party
- BZOJ 3377 [Usaco2004 Open]The Cow Lineup 奶牛序列
- USACO/cowtour