Chinaunix首页 | 论坛 | 博客
  • 博客访问: 556140
  • 博文数量: 127
  • 博客积分: 1169
  • 博客等级: 少尉
  • 技术积分: 1298
  • 用 户 组: 普通用户
  • 注册时间: 2010-03-16 14:29
个人简介

空白

文章分类

全部博文(127)

分类: C/C++

2012-03-23 23:58:13

一个笔试题目:
 n个人围成一个圈,第一个人从1开始递增报数,凡是报到3的倍数(包括3)时,该人退出,随后的人接着再继续报数,直到最后只剩下一个人为止,求最后剩下的这个人在原对中的编号。
思路:
用数组存储n个人,开始数组元素全部初始化为1,表示所有的人都在队中,然后循环遍历数组,凡是遇到能整除3的位置的元素就将该元素的值设为0; 同时记录队中1个数的count变量减一。重复上面的步骤,知道队中只有1个1时,循环退出,最后在遍历一次数组,找出值为1的这个元素所在的位置,就是最后剩下的这个人的原始编号。
实现:

  1. /*
  2.     时间:2012年3月22日 23:41:01
  3.     功能:笔试题:n个人围城一圈,第一个人从1开始递增报数,凡是报到3的倍数(包括3)时,该人退出,随后的人接着再继续报数,直到最后只剩下一个人为止,求最后剩下的这个人的编号。
  4.     思路:用数组存储n个人,开始数组元素全部初始化为1,表示所有的人都在队中,然后循环遍历数组,凡是遇到能整除3的位置的元素就将该元素的值设为0; 同时记录队中1个数的count变量减一。重复上面的步骤,知道队中只有1个1时,循环退出,最后在遍历一次数组,找出值为1的这个元素所在的位置,就是最后剩下的这个人的原始编号。
  5. */

  6. #include <stdio.h>
  7. #include <stdlib.h>

  8. int find(int n)
  9. {
  10.     int i;
  11.     int count = n; //count表示队中1的个数,开始1的个数与人数相等
  12.     int num = 1; //num记录是报数的数字,从1开始。
  13.     int *a = (int *)malloc(n * sizeof(int)); //为数组分配空间,这里不能写成a[n],数组是静态的,其大小必须明确。
  14.     if (NULL == a)
  15.     {
  16.         printf("内存分配失败,程序退出\n");
  17.         exit(-1);
  18.     }

  19.     //将数组全部数据初始化为1,1代表人还在队中
  20.     for(i = 0; i < n; i++)
  21.     {
  22.         a[i] = 1;
  23.     }

  24.     start:
  25.     for(i = 0; i < n; i++)
  26.     {
  27.         if (a[i] == 1) //检查第i个位置的人是否还在对中
  28.         {
  29.             if (num % 3 == 0) //如果还在,在检查他报数是否能整除3
  30.             {
  31.                 a[i] = 0; //如果能,将他退出
  32.                 count--; //队中人数减1
  33.             }
  34.             num++; //下一个报数
  35.         }

  36.         if (count == 1) //这里可以减少额外的循环
  37.             break;
  38.     }
  39.     
  40.     if (count != 1)
  41.         goto start;

  42.     for (i = 0; i < n; i++)
  43.     {
  44.         if (a[i] == 1)
  45.             return i + 1;
  46.     }

  47.     free(a); //最好释放动态分配的内存
  48.     return 0;
  49. }

  50. int main()
  51. {
  52.     int n;
  53.     printf("请输入人数: ");
  54.     scanf("%d", &n);
  55.     
  56.     printf("最后剩下的是 %d 个位置的人。\n", find(n));
  57.     return 0;
  58. }
测试结果:

  1. int main()
  2. {
  3.     int n;
  4.     printf("请输入人数: ");
  5.     scanf("%d", &n);
  6.     
  7.     printf("最后剩下的是 %d 个位置的人。\n", find(n));
  8.     return 0;
  9. }

  10. /*
  11.     在vc++6.0中输出的结果为:
  12.     ------------------------------------
  13.     请输入人数: 100
  14.     最后剩下的是 91 个位置的人。
  15.     -----------------------------------
  16.     请输入人数: 5
  17.     最后剩下的是 4 个位置的人。
  18.     -----------------------------------
  19. */
另一种实现(不用goto)

  1. /*第二种实现(不用goto)*/
  2. int find2(int n)
  3. {
  4.     int * a = (int *)malloc(n * sizeof(int));
  5.     if (NULL == a)
  6.     {
  7.         printf("内存分配失败,程序退出\n");
  8.         exit(-1);
  9.     }

  10.     int i, j = 0;
  11.     int count = n;
  12.     int num = 1;

  13.     for (i = 0; i < n; i++)
  14.     {
  15.         a[i] = 1;
  16.     }

  17.     while (1)
  18.     {
  19.         if(a[j] == 1)
  20.         {
  21.             if (num % 3 == 0)
  22.             {
  23.                 a[j] = 0;
  24.                 count--;
  25.             }
  26.             num++;
  27.         }

  28.         if (count == 1)
  29.             break;

  30.         j++;

  31.         if (j == n)
  32.         {
  33.             j = 0;
  34.         }
  35.     }

  36.     for (i = 0; i < n; i++)
  37.     {
  38.         if (a[i])
  39.         {
  40.             return i + 1;
  41.         }
  42.     }

  43.     free(a);
  44.     return 0;
  45. }
阅读(1544) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~