这是数学模型老师布置的一个作业题,发现用C语言可以很好的解决,只可惜那个水货老师看不懂!怎一个“悲”字了得!!!
题目:
任意拿出黑白两种颜色的棋子共八个,排成一个圆圈.然后在两颗颜色相同的棋子中间放一颗黑色棋子,在两颗颜色不同的棋子中间放一颗白色棋子,放完后撤掉原来所放的棋子.再重复以上的过程,这样放下一圈后就拿走前次的一圈棋子,问这样重复进行下去各棋子的颜色会怎样变化呢?
我的算法:
有8个黑白棋子,用0表示黑色,1表示白色。题目说:黑黑中间放黑棋,白白中间放黑棋,黑白中间放白棋。正好可以用位运算(异或)。
unsigned char 正好是8 bit, 正好可以模拟黑白棋状态,可以枚举所有情况(256种)。
一个数a表示一种状态,然后循环左移赋值给ta,a^ta就可以得出下一次8个棋子的状态,循环,直到某一次状态和前一次状态一样时,得出结果,退出循环.
我的代码:
#include<stdio.h>
unsigned char left_one(unsigned char x);//循环左移一位
void color(unsigned char x);//根据数字化状态装换成颜色
int p[8]={128,64,32,16,8,4,2,1};//辅助数组,以得出某一位是1还是0
int main()
{
int i,count,flag;
unsigned char a,b,ta,tb;//a,b表示前后两次的状态
for(i = 0 ; i < 256 ; ++i)//枚举256种情况
{
flag = 1;//a,b状态循环的依据
a = i;
b = i + 1 ;
printf("\n黑白棋初始状态:");
color(a);
count = 0 ;
while(a != b)
{
if(flag)
{
ta = left_one(a);
b = a ^ ta;
++count;
flag = 0;
}
else
{
tb = left_one(b);
a = b ^ tb;
++count;
flag = 1;
}
}//while()
printf("用的次数:%d \n",count-1);
printf("黑白棋最终状态:");
color(a);
}//for()
getchar();
return 0;
}
unsigned char left_one(unsigned char x)
{
unsigned char t = x << 1;
if(x&128) ++t;
return t;
}
void color(unsigned char x)
{
int i;
for( i = 0 ; i < 8 ; ++i )
{
if(x&p[i]) printf("白 ");
else printf("黑 ");
}
printf("\n");
}
结果:
最多八次,结果就稳定下来,最后全部为黑棋。
感受:
花了30min敲代码,花了3h调试好。值得,因为感觉没法继续优化了。哈哈!
位运算是个好东西!高效!神奇!