高效解决黑白棋问题
这是数学模型老师布置的一个作业题,发现用C语言可以很好的解决.
题目:
任意拿出黑白两种颜色的棋子共八个,排成一个圆圈.然后在两颗颜色相同的棋子中间放一颗黑色棋子,在两颗颜色不同的棋子中间放一颗白色棋子,放完后撤掉原来所放的棋子.再重复以上的过程,这样放下一圈后就拿走前次的一圈棋子,问这样重复进行下去各棋子的颜色会怎样变化呢?
我的算法:
有8个黑白棋子,用0表示黑色,1表示白色。题目说:黑黑中间放黑棋,白白中间放黑棋,黑白中间放白棋。正好可以用位运算(异或)。
unsigned char 正好是8 bit, 正好可以模拟黑白棋状态,可以枚举所有情况(256种)。
一个数a表示一种状态,然后循环左移赋值给ta,a^ta就可以得出下一次8个棋子的状态,循环,直到某一次状态和前一次状态一样时,得出结果,退出循环。
我的代码:
01.#include<stdio.h>
02.
03.unsigned char left_one(unsigned char x);//循环左移一位
04.void color(unsigned char x);//根据数字化状态装换成颜色
05.
06.
07.int p[8]={128,64,32,16,8,4,2,1};//辅助数组,以得出某一位是1还是0
08.
09.int main()
10.{
11. int i,count,flag;
12. unsigned char a,b,ta,tb;//a,b表示前后两次的状态
13.
14.
15. for(i = 0 ; i < 256 ; ++i)//枚举256种情况
16. {
17. flag = 1;//a,b状态循环的依据
18. a = i;
19. b = i + 1 ;
20. printf("\n黑白棋初始状态:");
21. color(a);
22.
23. count = 0 ;
24. while(a != b)
25. {
26. if(flag)
27. {
28. ta = left_one(a);
29. b = a ^ ta;
30. ++count;
31. flag = 0;
32. }
33. else
34. {
35. tb = left_one(b);
36. a = b ^ tb;
37. ++count;
38. flag = 1;
39. }
40. }//while()
41.
42. printf("用的次数:%d \n",count-1);
43. printf("黑白棋最终状态:");
44. color(a);
45.
46. }//for()
47.
48. getchar();
49. return 0;
50.}
51.
52.unsigned char left_one(unsigned char x)
53.{
54. unsigned char t = x << 1;
55. if(x&128) ++t;
56. return t;
57.}
58.
59.void color(unsigned char x)
60.{
61. int i;
62. for( i = 0 ; i < 8 ; ++i )
63. {
64. if(x&p[i]) printf("白 ");
65. else printf("黑 ");
66. }
67. printf("\n");
68.}
结果:
最多八次,结果就稳定下来,最后全部为黑棋。