圆圈报数:
10个人围成一个圈,从第一个开始报数,从1---3,报到3的人退出,求最后一个人的号码.设10个人的序号是从0---9.
此题可以用循环链表来做,每隔三个就删除一个结点,循环9次后即可得到最后一个结点.由于在学线性队列时,用到取余的方法可达到循环的效果,此时想到也可以用取余的方法来让其首尾相连(不直观).
先定义一个长度为10的数组aiPeople (值从1---10,与下标一致),再定义一个当前的下标iIndex, 初值为-1, 剩下人的个数iLeftNum.循环9次,每次循环都找出当前下标的后面起第三个有效值(非0,因为每次我找到一个,就给其赋值为0).
第一,二三次如图:
此时iIndex为8,为了首尾相连,以达到循环效果,可继续让其往后面加有效的三次, iIndex值为9,10,11每次判断iIndex对10取余是否有效(非0),即aiPeople[9], aiPeople[0], aiPeople[1],由于此三项都非0,故此时iIndex应为1. 这样就达到了循环. 不过要记住要找三次有效的值.
第四次: iIndex值:9,10(0),11(1),为1.
第五次时, iIndex值:2(无效),3,4,5(无效),6. 为6.
代码如下:
// TextArea.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
using namespace std ;
int _tmain(int argc, _TCHAR* argv[])
{
int aiPeople[10];
int iSize = int (sizeof ( aiPeople)/ sizeof ( aiPeople[0]));//
数组的大小
for ( int i= 0 ;i< iSize; ++i )
{
aiPeople[ i]= i + 1;
}
int iIndex= -1 ;//下标
int iLeftNum= 10;//剩余的个数
while ( iLeftNum >= 1 )
{
int iAddTimes = 0;
while ( iAddTimes < 3 )
{
++iIndex;
if ( aiPeople[ iIndex % 10] != 0 )
{
++iAddTimes;
}
}
if ( iIndex >= 10 )
{
iIndex= iIndex % 10;
}
aiPeople[ iIndex] = 0;
--iLeftNum;
}
cout <<"最后剩余的是 " << iIndex+ 1 <<endl ;
system("pause");
return 0;
}