USACO-Section 4.4 Shuttle Puzzle (BFS)
Posted 满赋诸机
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了USACO-Section 4.4 Shuttle Puzzle (BFS)相关的知识,希望对你有一定的参考价值。
描述
大小为3的棋盘游戏里有3个白色棋子,3个黑色棋子,和一个有7个格子一线排开的木盒子。3个白棋子被放在一头,3个黑棋子被放在另一头,中间的格子空着。
初始状态: WWW_BBB 目标状态: BBB_WWW
在这个游戏里有两种移动方法是允许的:
- 你可以把一个棋子移到与它相邻的空格;
- 你可以把一个棋子跳过一个(仅一个)与它不同色的棋子到达空格。
大小为N的棋盘游戏包括N个白棋子,N个黑棋子,还有有2N+1个格子的木盒子。
这里是3-棋盘游戏的解,包括初始状态,中间状态和目标状态:
WWW BBB WW WBBB WWBW BB WWBWB B WWB BWB W BWBWB WBWBWB BW WBWB BWBW WB BWBWBW BWBWB W BWB BWW B BWBWW BB WBWW BBBW WW BBB WWW
请编一个程序解大小为N的棋盘游戏(1 <= N <= 12)。要求用最少的移动步数实现。
格式
PROGRAM NAME: shuttle
INPUT FORMAT:
(file shuttle.in)
一个整数N。
OUTPUT FORMAT:
(file shuttle.out)
输出用移动的棋子在棋盘的位置(位置从左到右依次为1, 2, ..., 2N+1)表示的变换序列,每个数字之间以空格分隔,每行20个数(除了最后一行)。
输出的解还应当有最小的字典顺序(即如果有多组移动步数最小的解,输出第一个数最小的解;如果还有多组,输出第二个数最小的解;...)。
SAMPLE INPUT
3
SAMPLE OUTPUT
3 5 6 4 2 1 3 5 7 6 4 2 3 5 4
感觉这这种题和 魔板 与 八数码 差不多,轻易就能想到bfs
又是太依赖map了,感觉不用map就TLE了(只是按照要求写了互换的操作,并且指定B只能左移,W只能右移,但是还存在大量的无效状态,例如:空的一边有两个相同的W或B时,且在其外侧还有另一种字符(B或W),则无法达到最终状态)
/*
ID: your_id_here
PROG: shuttle
LANG: C++
*/
#include <cstdio>
#include <cstring>
#include <string>
#include <map>
#include <algorithm>
using namespace std;
struct Node
int i,pre;
char s[27];
Node()
memset(s,0,sizeof(s));
bool operator < (const Node& x) const
return strcmp(s+1,x.s+1)<0;
bool operator == (const Node& x) const
return strcmp(s+1,x.s+1)==0;
sta,des,u,v,q[100005];
int n,head,tail,ans[100005],cnt=0;
char ch;
map<Node,int> indx;
void bfs()
head=tail=1;
q[tail++]=sta;
indx[sta]=head;
while(head!=tail)
u=q[head++];
if(u.i>2&&u.s[u.i-1]=='B'&&u.s[u.i-2]=='W') //W隔一个B跳到空
v=u;
v.s[v.i-2]=' ';
v.s[v.i]='W';
v.i-=2;
v.pre=indx[u];
if(indx[v]==0)
if(v==des)
des.pre=v.pre;
return ;
q[tail]=v;
indx[v]=tail++;
if(u.i>1&&u.s[u.i-1]=='W') //W跳到相邻的空
v=u;
v.s[v.i-1]=' ';
v.s[v.i]='W';
--v.i;
v.pre=indx[u];
if(indx[v]==0)
if(v==des)
des.pre=v.pre;
return ;
q[tail]=v;
indx[v]=tail++;
if(u.i<n&&u.s[u.i+1]=='B') //B跳到相邻的空
v=u;
v.s[v.i+1]=' ';
v.s[v.i]='B';
++v.i;
v.pre=indx[u];
if(indx[v]==0)
if(v==des)
des.pre=v.pre;
return ;
q[tail]=v;
indx[v]=tail++;
if(u.i<n-1&&u.s[u.i+1]=='W'&&u.s[u.i+2]=='B') //B隔一个W跳到空
v=u;
v.s[v.i+2]=' ';
v.s[v.i]='B';
v.i+=2;
v.pre=indx[u];
if(indx[v]==0)
if(v==des)
des.pre=v.pre;
return ;
q[tail]=v;
indx[v]=tail++;
void print()
while(des.pre!=-1)
ans[cnt++]=des.i;
des=q[des.pre];
int tmp=0;
while(cnt>1)
printf("%d",ans[--cnt]);
if(++tmp==20)
tmp=0;
printf("\\n");
else
printf(" ");
printf("%d\\n",ans[0]);
int main()
freopen("shuttle.in","r",stdin);
freopen("shuttle.out","w",stdout);
scanf("%d",&n);
sta.pre=-1;
sta.i=des.i=n+1;
sta.s[n+1]=des.s[n+1]=' ';
for(int i=1;i<=n;++i)
sta.s[i]=des.s[n+1+i]='W';
des.s[i]=sta.s[n+1+i]='B';
n=(n<<1)+2;
bfs();
print();
return 0;
以上是关于USACO-Section 4.4 Shuttle Puzzle (BFS)的主要内容,如果未能解决你的问题,请参考以下文章
usaco-Section 2.3-Controlling Companies
使用 JointCode.Shuttle 进行跨 AppDomain 通信的一个简单示例