C趣味程序百例(28)黑白子交换

文章作者 100test 发表时间 2007:03:10 17:35:38
来源 100Test.Com百考试题网


87.黑白子交换
有三个白子和三个黑子如下图布置:
.

游戏的目的是用最少的步数将上图中白子和黑子的位置进行交换:
.

游戏的规则是:(1)一次只能移动一个棋子; (2)棋子可以向空格中移动,也可以跳过一个对方的棋子进入空格,但不能向后跳,也不能跳过两个子。请用计算机实现上述游戏。
*问题分析与算法设计
计算机解决胜这类问题的关键是要找出问题的规律,或者说是要制定一套计算机行动的规则。分析本题,先用人来解决问题,可总结出以下规则:
(1) 黑子向左跳过白子落入空格,转(5)
(2) 白子向右跳过黑子落入空格,转(5)
(3) 黑子向左移动一格落入空格(但不应产生棋子阻塞现象),转(5)
(4) 白子向右移动一格落入空格(但不应产生棋子阻塞现萌),转(5)
(5) 判断游戏是否结束,若没有结束,则转(1)继续。
所谓的“阻塞”现象就是:在移动棋子的过程中,两个尚未到位的同色棋子连接在一起,使棋盘中的其它棋子无法继续移动。例如按下列方法移动棋子:
0
.
1
.
2 △
.
3
.
4 两个●连在一起产生阻塞
.
或4 两个白连在一起产生阻塞
.

产生阻塞的现象的原因是在第2步(△状态)时,棋子○不能向右移动,只能将●向左移动。
总结产生阻塞的原因,当棋盘出现“黑、白、空、黑”或“白、空、黑、白”状态时,不能向左或向右移动中间的棋子,只移动两边的棋子。
按照上述规则,可以保证在移动棋子的过程中,不会出现棋子无法移动的现象,且可以用最少的步数完成白子和黑子的位置交换。
*程序与程序注释
#include
int number.
void print(int a[]).
void change(int *n,int *m).
void main()
{
int t[7]={1,1,1,0,2,2,2}. /*初始化数组1:白子 2:黑子 0:空格*/
int i,flag.
print(t).
while(t[0] t[1] t[2]!=6||t[4] t[5] t[6]!=3) /*判断游戏是否结束
若还没有完成棋子的交换则继续进行循环*/
{
flag=1. /*flag 为棋子移动一步的标记1:尚未移动棋子 0:已经移动棋子*/
for(i=0.flag&.&.i<5.i ) /*若白子可以向右跳过黑子,则白子向右跳*/
if(t[i]==1&.&.t[i 1]==2&.&.t[i 2]==0)
{change(&.t[i],&.t[i 2]). print(t). flag=0.}
for(i=0.flag&.&.i<5.i ) /*若黑子可以向左跳过白子,则黑子向左跳*/
if(t[i]==0&.&.t[i 1]==1&.&.t[i 2]==2)
{change(&.t[i],&.t[i 2]). print(t). flag=0.}
for(i=0.flag&.&.i<6.i ) /*若向右移动白子不会产生阻塞,则白子向右移动*/
if(t[i]==1&.&.t[i 1]==0&.&.(i==0||t[i-1]!=t[i 2]))
{change(&.t[i],&.t[i 1]). print(t).flag=0.}
for(i=0.flag&.&.i<6.i ) /*若向左移动黑子不会产生阻塞,则黑子向左移动*/
if(t[i]==0&.&.t[i 1]==2&.&.(i==5||t[i-1]!=t[i 2]))
{ change(&.t[i],&.t[i 1]). print(t).flag=0.}
}
}
void print(int a[])
{
int i.
printf("No. -:.............................\n",number ).
printf(" ").
for(i=0.i<=6.i )
printf(" | %c",a[i]==1?*:(a[i]==2?@: )).

相关文章


计算机等级考试Access二级免费资料1
考生是否必须通过第一(二)级才能报考第二(三)级?
C趣味程序百例(28)黑白子交换
C趣味编程百例(27)自动发牌
该考试每一级考试包括哪两部分?
澳大利亚华人论坛
考好网
日本华人论坛
华人移民留学论坛
英国华人论坛