题目描述
有2n个棋子(n≥4)排成一行,开始为位置白子全部在左边,黑子全部在右边,如下图为n=5的情况:
○○○○○●●●●●
移动棋子的规则是:每次必须同时移动相邻的两个棋子,颜色不限,可以左移也可以右移到空位上去,但不能调换两个棋子的左右位置。每次移动必须跳过若干个棋子(不能平移),要求最后能移成黑白相间的一行棋子。如n=5时,成为:
○●○●○●○●○●
任务:编程打印出移动过程。
输入输出格式
输入格式:
一个整数n(n<=50)
输出格式:
若干行,表示初始状态和每次移动的状态,用"o"表示白子,"x"表示黑子,"-"表示空行。
输入样例:
7
输出样例:
ooooooo*******-- oooooo--******o* oooooo******--o* ooooo--*****o*o* ooooo*****--o*o* oooo--****o*o*o* oooo****--o*o*o* ooo--***o*o*o*o* ooo*o**--*o*o*o* o--*o**oo*o*o*o* o*o*o*--o*o*o*o* --o*o*o*o*o*o*o*
这道题观察样例就会发现除了 n < 4 的时候,都是将 a[n - 1] 和 a[n] 的o*挪过去,再将 a[2n - 1] 和 a[2n - 2] 的 ** 挪过来。这样的话就可以循环输出 n >= 4 的情况。
至于 n < 4 呢,只需要将前半部分固输,后半部分加上 n - 4 个 o* 就行啦。
上代码
1 #include<cstdio> 2 #include<iostream> 3 #include<cmath> 4 #include<cstring> 5 #include<algorithm> 6 using namespace std; 7 const int maxn = 10005; 8 char a[maxn]; 9 int n; 10 void init(int n) 11 { 12 for(int i = 0; i < n; ++i) a[i] = ‘o‘; 13 for(int i = n; i < 2 * n; ++i) a[i] = ‘*‘; 14 a[2 * n] = a[2 * n + 1] = ‘-‘; 15 return; 16 } 17 void solve(int n) 18 { 19 a[n - 1] = a[n] = ‘-‘; 20 a[2 * n] = ‘o‘; 21 a[2 * n + 1] = ‘*‘; 22 printf("%s\n", a); 23 a[n - 1] = a[n] = ‘*‘; 24 a[2 * n - 1] = a[2 * n - 2] = ‘-‘; 25 printf("%s\n", a); 26 return; 27 } 28 void fstnoutput() 29 { 30 printf("ooo--***o*"); 31 for(int i = 1; i <= n - 4;++i) printf("o*"); 32 printf("\n"); 33 printf("ooo*o**--*"); 34 for(int i = 1; i <= n - 4;++i) printf("o*"); 35 printf("\n"); 36 printf("o--*o**oo*"); 37 for(int i = 1; i <= n - 4;++i) printf("o*"); 38 printf("\n"); 39 printf("o*o*o*--o*"); 40 for(int i = 1; i <= n - 4;++i) printf("o*"); 41 printf("\n"); 42 printf("--o*o*o*o*"); 43 for(int i = 1; i <= n - 4;++i) printf("o*"); 44 printf("\n"); 45 return; 46 } 47 int main() 48 { 49 scanf("%d", &n); 50 init(n); 51 int m = n; 52 printf("%s\n", a); 53 while(m > 4) 54 { 55 solve(m); 56 m--; 57 } 58 fstnoutput(); 59 return 0; 60 }
我觉得这题挺水的。
不过在分标签的时候我犹豫了好久,最终觉得它就算递归递推了吧,虽然这道题是我在学分治时候出的。【尴尬】