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;
}

  

转载于:https://www.cnblogs.com/doublemystery/archive/2013/04/11/3015079.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值