开始试图找挪动的规律,找了半天,成功的挪动规律虽然没找到,但发现了失败的规律。如果出现两个连续的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;
}