USACO 4.4.1 Shuttle Puzzle 棋盘游戏 题解与分析
2013-09-17 21:52
423 查看
Shuttle Puzzle棋盘游戏译 by Jeru
描述
大小为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: shuttleINPUT 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
【分析】:
DFS优化。首先,对一个长度为2*N+1的数组染色<在程序中1代表W,2代表B>,然后DFS,为满足字典序最小,那么顺序应该为:右2<空格左移2>→右1<空格左移1>→左1<空格右移1>→左2<空格右移2>,这样保证空格的位置的字典序最小。由公式推导,最小步数为N*(N+2),即DFS的层数为N*(N+2)。在移动过程中的优化:然后看W和B的整体移动方向:W整体向右移,B整体向左移,那么可以优化为W只向右移,B只向左移,这样程序效率也很不错
【代码】:
/* ID:csyzcyj1 PROG:shuttle LANG:C++ */ #include<stdio.h> #include<string.h> #include<stdlib.h> #include<algorithm> #include<iostream> #include<vector> #include<stack> #include<queue> using namespace std; #define MAX 180 #define IMAX 21474836 int N; int now[MAX],ans[MAX]; void pre_makestring() { for(int i=1;i<=N;i++) now[i]=1;//1代表‘W’ for(int i=N+2;i<=2*N+1;i++) now[i]=2;//2代表‘B’ } void swap(int &x,int &y){int t;t=x,x=y,y=t;} void putout() { int tot=0; for(int i=1;i<=N*(N+2);i++) { if(tot%20==0) printf("%d",ans[i]); else printf(" %d",ans[i]); tot++; if(tot%20==0) printf("\n"); } if(tot%20) printf("\n"); } void work(int empty,int floor) { if(empty-2>0 && now[empty-2]==1 && now[empty-1]==2)//向右跳两格 { swap(now[empty-2],now[empty]); ans[floor]=empty-2; if(floor==N*(N+2) && empty-2==N+1) {putout();return;} else if(floor<N*(N+2)) work(empty-2,floor+1); swap(now[empty-2],now[empty]); } if(empty-1>0 && now[empty-1]==1)//向右跳一格 { swap(now[empty-1],now[empty]); ans[floor]=empty-1; if(floor==N*(N+2) && empty-1==N+1) {putout();return;} else if(floor<N*(N+2)) work(empty-1,floor+1); swap(now[empty-1],now[empty]); } if(empty+1<=2*N+1 && now[empty+1]==2)//向左跳一格 { swap(now[empty+1],now[empty]); ans[floor]=empty+1; if(floor==N*(N+2) && empty+1==N+1) {putout();return;} if(floor<N*(N+2)) work(empty+1,floor+1); swap(now[empty+1],now[empty]); } if(empty+2<=2*N+1 && now[empty+2]==2 && now[empty+1]==1)//向左跳两格 { swap(now[empty+2],now[empty]); ans[floor]=empty+2; if(floor==N*(N+2) && empty+2==N+1) {putout();return;} if(floor<N*(N+2)) work(empty+2,floor+1); swap(now[empty+2],now[empty]); } } int main() { freopen("shuttle.in","r",stdin); freopen("shuttle.out","w",stdout); scanf("%d",&N); pre_makestring(); work(N+1,1); //system("pause"); return 0; }【评测信息】: TASK: shuttle LANG: C++ Compiling... Compile: OK Executing... Test 1: TEST OK [0.011 secs, 3376 KB] Test 2: TEST OK [0.011 secs, 3376 KB] Test 3: TEST OK [0.011 secs, 3376 KB] Test 4: TEST OK [0.011 secs, 3376 KB] Test 5: TEST OK [0.000 secs, 3376 KB] Test 6: TEST OK [0.000 secs, 3376 KB] Test 7: TEST OK [0.011 secs, 3376 KB] Test 8: TEST OK [0.011 secs, 3376 KB] Test 9: TEST OK [0.011 secs, 3376 KB] Test 10: TEST OK [0.011 secs, 3376 KB] All tests OK. 转载注明出处:http://blog.csdn.net/u011400953
相关文章推荐
- USACO 4.3.4 Letter Game 字母游戏 题解与分析
- USACO Training 3.4.2 American Heritage 题解与分析
- usaco4.4.1 Shuttle Puzzle
- USACO4.4.1 Shuttle Puzzle (shuttle)
- USACO Training 4.2.3 Job Processing 工序安排 题解与分析
- USACO4.4.1 Shuttle Puzzle (shuttle)
- USACO 5.1.1 Fencing the Cows 圈奶牛 题解与分析
- USACO Training 5.3.3 Network of Schools 校园网 题解与分析
- C++——【USACO 4.4.1】——Shuttle Puzzle
- [USACO 4.4.1 Shuttle Puzzle]
- USACO Training 3.3.3 Camelot 亚瑟王的宫殿 题解与分析
- 求解和为15的棋盘游戏问题的代码分析
- BZOJ 1854 [Scoi2010] 游戏 题解与分析
- 洛谷P1345 [USACO5.4]奶牛的电信Telecowmunication【最小割】分析+题解代码
- USACO Training 4.2.1 Drainage Ditches 草地排水 题解与分析<网络流DINIC算法>
- USACO 4.4.2 Pollutant Control追查坏牛奶 题解与分析
- BZOJ 2438 [中山市选2011] 杀人游戏 题解与分析
- BZOJ 1601 [Usaco2008 Oct]灌水 题解与分析
- USACO 4.4.3 Frame Up 重叠的图像 题解与分析
- BZOJ 1022 [SHOI2008]小约翰的游戏John 题解与分析