1. 程式人生 > >助教c/c++:n個人圍成一圈報數問題

助教c/c++:n個人圍成一圈報數問題

以下三個問題都屬於同類型的問題,其中兩道題目是助教時的實驗題,還有一道是華為在成都招聘時的機試題目。

在這三個問題中,問題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;
}

執行結果: