10个小孩围成一圈分糖果,老师分给第1个小孩10块,第2个小孩2块,第3个小孩8块,第4个小孩22块,第5个小孩16块,第6个小孩4块,第7个小孩10块,第8 个小孩6块,第9个小孩14块,第10个小孩20块。然后所有的小孩同时将手中的糖分一半给右边的小孩;糖块数为奇数的人可向老师要一块。问经过这样几次后大家手中的糖块数一样多吗?每人各有多少块糖?
这是一个典型的可使用循环结构来解决的问题。老师开始给每个小孩分配的糖果数作为循环的初始条件,“所有的小孩同时将手中的糖分一半给右边的小孩;糖块数为奇数的人可向老师要一块”这个重复的动作作为循环体,循环的结束条件为所有小孩手中的糖块数一样多。在循环体中,还需要判断糖块数的奇偶性,奇偶性不同,完成的操作也不相同,显然这需要使用一个选择结构来实现。
使用数组来存放老师开始给每个小孩分配的糖果数,因为有10个小孩,因此定义一个长度为10的整型数组即可。在循环过程中,糖果每经过一次重新分配,就打印输出一次,直到10个小孩所拥有的糖果数都相同,此时结束循环。所以还应加上判断程序,条件为10个小孩所拥有的糖果数都相同。
程序流程图如下:
下面是完整的代码:
#include<stdio.h>
void print(int s[]);
int judge(int c[]);
int j=0;
int main()
{
int sweet[10] = { 10, 2, 8, 22, 16, 4, 10, 6, 14, 20 }; /*初始化数组数据*/
int i, t[10], l;
printf("child 1 2 3 4 5 6 7 8 9 10\n");
printf("………………………………………………………………\n");
printf("time\n");
print(sweet); /*输出每个人手中糖的块数*/
while( judge(sweet) ) /*若不满足要求则继续进行循环*/
{
for( i=0; i<10; i++ ) /*将每个人手中的糖分成一半*/
if(sweet[i]%2 == 0) /*若为偶数则直接分出一半*/
t[i] = sweet[i] = sweet[i]/2;
else /*若为奇数则加1后再分出一半*/
t[i] = sweet[i] = (sweet[i]+1)/2;
for( l=0; l<9; l++ ) /*将分出的一半糖给右(后)边的孩子*/
sweet[l+1] = sweet[l+1] + t[l];
sweet[0] += t[9];
print(sweet); /*输出当前每个孩子中手中的糖果数*/
}
return 0;
}
int judge( int c[] )
{
int i;
for( i=0; i<10; i++) /*判断每个孩子手中的糖果数是否相同*/
if(c[0]!=c[i])
return 1; /*不相同返回1*/
return 0;
}
/*输出数组中每个元素的值*/
void print(int s[])
{
int k;
printf(" %2d:", j++);
for( k=0; k<10; k++ )
printf("%4d", s[k]);
printf("\n");
}
运行结果:
int judge( int c[] )
{
int i;
for( i=0; i<10; i++ ) /*判断每个孩子手中的糖果数是否相同*/
if(c[0]!=c[i])
return 1; /*不相同返回1*/
return 0;
}
当指针 c 接收了实参数组 sweet 的首元素地址时,c 就指向了 sweet 数组的首元素,即 sweet[0],则 *c 的值就是 sweet[0] 的值。而 c+1 就指向了 sweet[1],c+2 就指向了 sweet[2],依次类推,c+i 就指向了 sweet[i],那么 *(c+1)、*(c+2) 和 *(c+i) 就分别是数组元素sweet[1]、sweet[2] 和 sweet[i] 的值。这样就通过调用 judge() 函数改变了实参数组 sweet 中数组元素的值。