Shuttle Puzzle[USACO]
开始试图找挪动的规律,找了半天,成功的挪动规律虽然没找到,但发现了失败的规律。如果出现两个连续的W或B,而它的连续没能连续到边界,则铁定失败。如:...W..BB..W.. 或者 ..B..WW..B..
于是,可以递归挪动了~,速度很快,基本为0
/* ID: zhangyc1 LANG: C++ TASK: shuttle */ #include <fstream> #include <iostream> #include <string> #include <cstring> #include <cstdlib> #include <stack> using namespace std; stack<int> s; int N, nBLeft = 0, nWRight = 0; ofstream fileout("shuttle.out"); char strShuttle[26]; int nLineCount = 0; void prepairData() { ifstream filein("shuttle.in"); filein >> N; filein.close(); memset(strShuttle, 'W', N); strShuttle[N] = ' '; memset(strShuttle + N + 1, 'B', N); } inline void record(int i) { s.push(i+1); } bool move(int nPosSpace, int nStep) { if (nBLeft == N && nWRight == N) { return true; } // 判断上次移动是否造成了 ...W..BB..W.. 或者 ..B..WW..B..出现,如有,则本次移动失败 bool bDuplicate = false; int nCheckPos = nPosSpace - nStep; if (nCheckPos > 0 && strShuttle[nCheckPos] == strShuttle[nCheckPos - 1]) {// 左侧发生的重复,必为B if (nBLeft != nCheckPos + 1) { bDuplicate = true; } } else if (nCheckPos < 2*N && strShuttle[nCheckPos] == strShuttle[nCheckPos + 1]) {// 右侧发生的重复,必为W if (nWRight != 2 * N + 1 - nCheckPos) { bDuplicate = true; } } if (bDuplicate) return false; //依次尝试左2,左1,右1,右2的移动 if (nPosSpace >= 2 && strShuttle[nPosSpace - 2] == 'W' && strShuttle[nPosSpace - 1] == 'B') { strShuttle[nPosSpace] = 'W', strShuttle[nPosSpace - 2] = ' '; nBLeft--, nWRight++; if (move(nPosSpace - 2, -2)) { record(nPosSpace - 2); return true; } strShuttle[nPosSpace] = ' ', strShuttle[nPosSpace - 2] = 'W'; nBLeft++, nWRight--; } if (nPosSpace >= 1 && strShuttle[nPosSpace - 1] == 'W') { strShuttle[nPosSpace] = 'W', strShuttle[nPosSpace - 1] = ' '; nWRight++; if (move(nPosSpace - 1, -1)) { record(nPosSpace - 1); return true; } strShuttle[nPosSpace] = ' ', strShuttle[nPosSpace - 1] = 'W'; nWRight--; } if (nPosSpace <= 2*N-1 && strShuttle[nPosSpace + 1] == 'B') { strShuttle[nPosSpace] = 'B', strShuttle[nPosSpace + 1] = ' '; nBLeft++; if (move(nPosSpace + 1, 1)) { record(nPosSpace + 1); return true; } strShuttle[nPosSpace] = ' ', strShuttle[nPosSpace + 1] = 'B'; nBLeft--; } if (nPosSpace <= 2*N-2 && strShuttle[nPosSpace + 1] == 'W' && strShuttle[nPosSpace + 2] == 'B') { strShuttle[nPosSpace] = 'B', strShuttle[nPosSpace + 2] = ' '; nBLeft++, nWRight--; if (move(nPosSpace + 2, 2)) { record(nPosSpace + 2); return true; } strShuttle[nPosSpace] = ' ', strShuttle[nPosSpace + 2] = 'B'; nBLeft--, nWRight++; } return false; } void process() { nWRight = 1; strShuttle[N] = 'W'; strShuttle[N-1] = ' '; move(N - 1, -1); fileout << N; nLineCount = 1; while (!s.empty()) { int nTemp = s.top(); s.pop(); if (nLineCount % 20 == 0) fileout << endl; else fileout << " "; fileout << nTemp; nLineCount++; } fileout << endl; } int main(){ prepairData(); process(); fileout.close(); return 0; }