大小为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个数(除了最后一行)。
输出的解还应当有最小的字典顺序(即如果有多组移动步数最小的解,输出第一个数最小的解;如果还有多组,输出第二个数最小的解;...)。
3
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; }