The Primes[USACO]
这道题无论横着,竖着,一行/列来整体放都会超时,想不到什么好办法。只好写了个超长的switch case语句,想清楚瞅仔细,就省得调试麻烦了。
//00-17-11-18-03 //21-04-22-08-15 //12-19-05-20-10 //23-07-24-06-16 //02-13-09-14-01
上图是处理顺序,从00--24. 实际只用了15个case,因为有一些是可以计算出来的。之所以是这个顺序是为了把循环次数小的case放前头。运行速度还是很快的。
/* ID: zhangyc1 LANG: C++ TASK: prime3 */ //00-17-11-18-03 //21-04-22-08-15 //12-19-05-20-10 //23-07-24-06-16 //02-13-09-14-01 #include <fstream> #include <iostream> #include <string> #include <sstream> #include <cstring> #include <cstdlib> #include <vector> #include <algorithm> using namespace std; stringstream os; ofstream fileout("prime3.out"); int nFirstNum, nCommonSum; // 因为sqrt(99999)=316.23,计算base为 int arrBasePrimeSet[100], nSizeBasePrimeSet = 0; bool arrIsPrime[10][10][10][10][10]; bool bFound = false; int arrMul[5] = {10000, 1000, 100, 10, 1}; int arrLastNum[4] = {1, 3, 7, 9}; int arrSumLine[5], arrSumCol[5], arrSumDia[2]; vector<string> vtRs; int arrNum[5][5]; void getBasePrimeSet() // 筛法求2-317内素数 { bool arrIsPrime[318]; memset(arrIsPrime, 1, sizeof(arrIsPrime)); int nPos = 2; while (nPos < 318) { arrBasePrimeSet[nSizeBasePrimeSet] = nPos; nSizeBasePrimeSet++; int nThresh = 317 / nPos; for (int i = 2; i < nThresh; i++) { arrIsPrime[i * nPos] = false; } nPos++; while (nPos < 318 && arrIsPrime[nPos] == false) nPos++; } } // 10000至99999内满足和为nCommonSum void getValidPrimeSet() { int arrDigit[5]; for (int i = 10001; i <= 99999; i++) { int nTemp = i; for (int j = 4; j >= 0; j--) { arrDigit[j] = nTemp % 10; nTemp /= 10; } if (arrDigit[0] + arrDigit[1] + arrDigit[2] + arrDigit[3] + arrDigit[4] == nCommonSum) { bool bValid = true; for (int j = 0; j < nSizeBasePrimeSet; j++) { if (i % arrBasePrimeSet[j] == 0) { bValid = false; break; } } if (bValid) { arrIsPrime[arrDigit[0]][arrDigit[1]][arrDigit[2]][arrDigit[3]][arrDigit[4]] = true; } } } } void prepairData() { ifstream filein("prime3.in"); filein >> nCommonSum >> nFirstNum; filein.close(); memset(arrIsPrime, 0, sizeof(arrIsPrime)); } void recordRs() { for (int i = 0; i < 5; i++) { for (int j = 0; j < 5; j++) { os << arrNum[i][j]; } } string str; os >> str; os.clear(); vtRs.push_back(str); } void dfs(int nDepth) { switch (nDepth) { case 0: arrNum[0][0] = nFirstNum; arrSumLine[0] = nFirstNum; arrSumCol[0] = nFirstNum; arrSumDia[0] = nFirstNum; dfs(1); break; case 1: for (int i = 0; i < 4; i++) { arrNum[4][4] = arrLastNum[i]; arrSumLine[4] += arrLastNum[i]; arrSumCol[4] += arrLastNum[i]; arrSumDia[0] += arrLastNum[i]; if (arrSumLine[4] <= nCommonSum && arrSumCol[4] <= nCommonSum && arrSumDia[0] <= nCommonSum) { dfs(2); } arrSumLine[4] -= arrLastNum[i]; arrSumCol[4] -= arrLastNum[i]; arrSumDia[0] -= arrLastNum[i]; } break; case 2: for (int i = 0; i < 4; i++) { arrNum[4][0] = arrLastNum[i]; arrSumLine[4] += arrLastNum[i]; arrSumCol[0] += arrLastNum[i]; arrSumDia[1] += arrLastNum[i]; if (arrSumLine[4] <= nCommonSum && arrSumCol[0] <= nCommonSum && arrSumDia[1] <= nCommonSum) { dfs(3); } arrSumLine[4] -= arrLastNum[i]; arrSumCol[0] -= arrLastNum[i]; arrSumDia[1] -= arrLastNum[i]; } break; case 3: for (int i = 0; i < 4; i++) { arrNum[0][4] = arrLastNum[i]; arrSumLine[0] += arrLastNum[i]; arrSumCol[4] += arrLastNum[i]; arrSumDia[1] += arrLastNum[i]; if (arrSumLine[0] <= nCommonSum && arrSumCol[4] <= nCommonSum && arrSumDia[1] <= nCommonSum) { dfs(4); } arrSumLine[0] -= arrLastNum[i]; arrSumCol[4] -= arrLastNum[i]; arrSumDia[1] -= arrLastNum[i]; } break; case 4: for (int i = 0; i <= 9; i++) { arrNum[1][1] = i; arrSumLine[1] += i; arrSumCol[1] += i; arrSumDia[0] += i; if (arrSumLine[1] <= nCommonSum && arrSumCol[1] <= nCommonSum && arrSumDia[0] <= nCommonSum) { dfs(5); } arrSumLine[1] -= i; arrSumCol[1] -= i; arrSumDia[0] -= i; } break; case 5: for (int i = 0; i <= 9; i++) { int nLeft = nCommonSum - i - arrSumDia[0]; if (nLeft >= 0 && nLeft <= 9 && arrIsPrime[arrNum[0][0]][arrNum[1][1]][i][nLeft][arrNum[4][4]]) { arrNum[2][2] = i; arrNum[3][3] = nLeft; arrSumLine[2] += i, arrSumLine[3] += nLeft; arrSumCol[2] += i, arrSumCol[3] += nLeft; arrSumDia[0] = nCommonSum; arrSumDia[1] += i; dfs(7); arrSumLine[2] -= i, arrSumLine[3] -= nLeft; arrSumCol[2] -= i, arrSumCol[3] -= nLeft; arrSumDia[0] = nCommonSum - i - nLeft; arrSumDia[1] -= i; } } break; case 7: for (int i = 0; i <= 9; i++) { int nLeft = nCommonSum - i - arrSumDia[1]; if (nLeft >= 0 && nLeft <= 9 && arrIsPrime[arrNum[4][0]][i][arrNum[2][2]][nLeft][arrNum[0][4]]) { arrNum[3][1] = i; arrNum[1][3] = nLeft; arrSumLine[3] += i, arrSumLine[1] += nLeft; arrSumCol[1] += i, arrSumCol[3] += nLeft; arrSumDia[1] = nCommonSum; dfs(9); arrSumLine[3] -= i, arrSumLine[1] -= nLeft; arrSumCol[1] -= i, arrSumCol[3] -= nLeft; arrSumDia[1] = nCommonSum - i - nLeft; } } break; case 9: for (int i = 0; i < 4; i++) { arrNum[4][2] = arrLastNum[i]; arrSumLine[4] += arrLastNum[i]; arrSumCol[2] += arrLastNum[i]; if (arrSumLine[4] <= nCommonSum && arrSumCol[2] <= nCommonSum) { dfs(10); } arrSumLine[4] -= arrLastNum[i]; arrSumCol[2] -= arrLastNum[i]; } break; case 10: for (int i = 0; i < 4; i++) { arrNum[2][4] = arrLastNum[i]; arrSumLine[2] += arrLastNum[i]; arrSumCol[4] += arrLastNum[i]; if (arrSumLine[2] <= nCommonSum && arrSumCol[4] <= nCommonSum) { dfs(11); } arrSumLine[2] -= arrLastNum[i]; arrSumCol[4] -= arrLastNum[i]; } break; case 11: for (int i = 1; i <= 9; i++) { arrNum[0][2] = i; arrSumLine[0] += i; arrSumCol[2] += i; if (arrSumLine[0] <= nCommonSum && arrSumCol[2] <= nCommonSum) { dfs(12); } arrSumLine[0] -= i; arrSumCol[2] -= i; } break; case 12: for (int i = 1; i <= 9; i++) { arrNum[2][0] = i; arrSumLine[2] += i; arrSumCol[0] += i; if (arrSumLine[2] <= nCommonSum && arrSumCol[0] <= nCommonSum) { dfs(13); } arrSumLine[2] -= i; arrSumCol[0] -= i; } break; case 13: for (int i = 0; i < 4; i++) { int nLeft = nCommonSum - arrSumLine[4] - arrLastNum[i]; if (nLeft > 0 && nLeft <= 9 && arrIsPrime[arrNum[4][0]][arrLastNum[i]][arrNum[4][2]][nLeft][arrNum[4][4]]) { arrNum[4][1] = arrLastNum[i], arrNum[4][3] = nLeft; arrSumLine[4] = nCommonSum; arrSumCol[1] += arrLastNum[i], arrSumCol[3] += nLeft; dfs(15); arrSumLine[4] -= nLeft + arrLastNum[i]; arrSumCol[1] -= arrLastNum[i], arrSumCol[3] -= nLeft; } } break; case 15: for (int i = 0; i < 4; i++) { int nLeft = nCommonSum - arrSumCol[4] - arrLastNum[i]; if (nLeft > 0 && nLeft <= 9 && arrIsPrime[arrNum[0][4]][arrLastNum[i]][arrNum[2][4]][nLeft][arrNum[4][4]]) { arrNum[1][4] = arrLastNum[i], arrNum[3][4] = nLeft; arrSumCol[4] = nCommonSum; arrSumLine[1] += arrLastNum[i], arrSumLine[3] += nLeft; dfs(17); arrSumCol[4] -= nLeft + arrLastNum[i]; arrSumLine[1] -= arrLastNum[i], arrSumLine[3] -= nLeft; } } break; case 17: for (int i = 1; i <= 9; i++) { int nLeft1 = nCommonSum - arrSumLine[0] - i; int nLeft2 = nCommonSum - arrSumCol[1] - i; int nLeft3 = nCommonSum - arrSumLine[2] - nLeft2; if (nLeft1 > 0 && nLeft1 <= 9 && nLeft2 >= 0 && nLeft2 <= 9 && nLeft3 >= 0 && nLeft3 <= 9 && nLeft1 + nLeft3 + arrSumCol[3] == nCommonSum && arrIsPrime[arrNum[0][0]][i][arrNum[0][2]][nLeft1][arrNum[0][4]] && arrIsPrime[arrNum[2][0]][nLeft2][arrNum[2][2]][nLeft3][arrNum[2][4]] && arrIsPrime[i][arrNum[1][1]][nLeft2][arrNum[3][1]][arrNum[4][1]] && arrIsPrime[nLeft1][arrNum[1][3]][nLeft3][arrNum[3][3]][arrNum[4][3]]) { arrNum[0][1] = i, arrNum[0][3] = nLeft1, arrNum[2][1] = nLeft2, arrNum[2][3] = nLeft3; arrSumLine[0] = arrSumLine[2] = arrSumCol[1] = arrSumCol[3] = nCommonSum; dfs(21); arrSumLine[0] -= i + nLeft1, arrSumLine[2] -= nLeft2 + nLeft3; arrSumCol[1] -= i + nLeft2, arrSumCol[3] -= nLeft1 + nLeft3; } } break; case 21: for (int i = 1; i <= 9; i++) { int nLeft1 = nCommonSum - arrSumLine[1] - i; int nLeft2 = nCommonSum - arrSumCol[0] - i; int nLeft3 = nCommonSum - arrSumLine[3] - nLeft2; if (nLeft2 > 0 && nLeft2 <= 9 && nLeft1 >= 0 && nLeft1 <= 9 && nLeft3 >= 0 && nLeft3 <= 9 && nLeft1 + nLeft3 + arrSumCol[2] == nCommonSum && arrIsPrime[i][arrNum[1][1]][nLeft1][arrNum[1][3]][arrNum[1][4]] && arrIsPrime[nLeft2][arrNum[3][1]][nLeft3][arrNum[3][3]][arrNum[3][4]] && arrIsPrime[arrNum[0][0]][i][arrNum[2][0]][nLeft2][arrNum[4][0]] && arrIsPrime[arrNum[0][2]][nLeft1][arrNum[2][2]][nLeft3][arrNum[4][2]]) { arrNum[1][0] = i, arrNum[3][0] = nLeft2, arrNum[1][2] = nLeft1, arrNum[3][2] = nLeft3; recordRs(); } } break; } } void process() { getBasePrimeSet(); getValidPrimeSet(); dfs(0); if (vtRs.size() == 0) { fileout << "NONE\n"; } else { sort(vtRs.begin(), vtRs.end()); string strTemp; for (vector<string>::const_iterator it = vtRs.begin(); it != vtRs.end(); it++) { if (it != vtRs.begin()) { fileout << endl; } strTemp = *it; fileout << strTemp.substr(0, 5) << "\n" << strTemp.substr(5, 5) << "\n" << strTemp.substr(10, 5) << "\n" << strTemp.substr(15, 5) << "\n" << strTemp.substr(20, 5) << "\n"; } } } int main(){ prepairData(); process(); fileout.close(); return 0; }