以下三个问题都属于同类型的问题,其中两道题目是助教时的实验题,还有一道是华为在成都招聘时的机试题目。
在这三个问题中,问题1考虑的最简单,用指针实现;问题2考虑最全面,用结构体实现;问题3用到了函数。
问题1:有n个人围成一圈,顺序排号。从第一个人开始报数,凡报到3的人退出圈子,问最后留下的是几号?
源程序:
#include<stdio.h>
#define max 15
int main()
{
int i,k,n,m,num[max],*p;
printf("输入开始报数时总人数:");
scanf("%d",&n);//开始报数前的人数。
p=num;//指针指向数组第一位num[0]
for(i=0;i<n;i++)//把n个人进行编号为1—n。
*(p+i)=i+1;
printf("依次出圈的人的编号:");
i=0;k=0;m=0;
while(m<n-1)//m为圈外人数。当m=n-1时,不再执行while循环,此时圈内还有一个人。
{
if(*(p+i)!=0)//报数。
k++;
if(k==3)
{
printf("%d ",*(p+i));//按顺序依次输出出圈的人的编号。
*(p+i)=0;//对于出圈人数,其值置为0。
m++;//圈外人数加1。
k=0;//重新开始报数。
}
i++;//指针指向下一位。
if(i==n)//指针移到最后一位时,重新赋值
i=0;//printf("\n");
}
for(i=0;i<n;i++)//输出最后一位出圈的人的编号
if(*(p+i)!=0)
printf("\n最后一位出圈的人的编号:%d\n",*(p+i));
return 0;
}
运行结果:
问题2:n个人围成一圈,从第s个人开始按顺时针1,2,3,4,……,m的顺序报数,数到m的人出圈,然后从出圈的下一个人开始重复此过程,输出所有出圈人的顺序。
要求:结构体指针。
源程序:
#include<stdio.h>
#define N 10
struct child
{
int no;
int next;
};
struct child link[N];
void main()
{
int i,n,m,s,count,h;//定义变量
printf("输入围圈人数,出圈报数,开始报数位置:");
scanf("%d,%d,%d",&n,&m,&s);//n是总人数,m是出圈号,s是初始报数位置。
for(i=1;i<=n;i++)
{
if(i==n)link[i].next=1;//围成一圈,
else link[i].next=i+1;
link[i].no=i;
}
count=0;
if(s==1)h=n;
else h=s-1;
//如果从1号开始报数,1号的前一位是n号。如果从s开始报数,s的前一位是s-1号。
printf("出圈顺序为:");
while(count<n-1)//count是圈外人数,当count=n-1时,不再执行while循环,圈内还剩下一人。
{
i=0;
while(i!=m)
{
h=link[h].next;
if(link[h].no)//判断当前号的值是否已置0,
i++;
}
printf("%d ",link[h].no);//依次输出出圈的人的编号
link[h].no=0;
count++;
}
printf("\n最后出圈的人的编号:");
for(i=1;i<=n;i++)//最后出圈的人的编号
if(link[i].no!=0)
printf("%d",link[i].no);
}
运行结果:
问题3:#华为机试#
计算最后一个出列者的编号
描述: 现在有n个竞争者围坐一圈,争夺一个很有吸引力的工作(年薪100w $)。假设这些人编号1,2,。。。,n。第一次从1开始报数,数到m(m>0)的那个人出列,它的下一位又从1开始报数,数到m的那个人又出列。以此类推,直到所有人出列为止。老板说最后一个出列的人将获得这份工作。
如果你也想竞争这份工作,那么你会坐着哪个位置上?
实现一个函数,当老板告诉你n和m时,返回得到工作的那个人的编号。
运行时间限制: 无限制
内存限制: 无限制
输入: 竞争者人数,报数
输出: 最后出列的竞争者的编号。异常则返回 -1。
样例输入: 10,10
样例输出: 8
源程序:
#include<stdio.h>
void main()
{
int search(int n,int m);
int n,m,lucky;//定义变量
printf("竞争者人数,出圈报数:");
scanf("%d,%d",&n,&m);//n是总人数,m是出圈号,s是初始报数位置。
lucky=search(n,m);
if(lucky==-1)
printf("异常!!!");
else
printf("幸运者编号:%d\n",lucky);
}
int search(int n,int m)
{
int num[20];int *p=num;
int i,j,k,count,h,lucky=-1;
for(i=0;i<n;i++)
{
*(p+i)=i+1;
}
count=0;j=0;
h=n;i=0;k=0;//从第1号开始报数,1号的前一位是n号。
while(count<n-1)//count是圈外人数,当count=n-1时,不再执行while循环,圈内还剩下1人。
{
if(*(p+i)!=0)k++;
if(k==m)
{
*(p+i)=0;
k=0;
count++;
}
i++;
if(i==n)
i=0;
}
for(i=0;i<n;i++)//最后出圈的人的编号
if(*(p+i)!=0)
lucky=*(p+i);
return lucky;
}
运行结果: