有n个人围成一圈,顺序排号。从第1个人开始报数(从1到3报数), 凡报到3的人退出圈子,问最后留下的是原来第几号的那位。

  • Post author:
  • Post category:其他


有n个人围成一圈,顺序排号。从第1个人开始报数(从1到3报数), 凡报到3的人退出圈子,问最后留下的是原来第几号的那位。

方法一:(用指针指向malloc开辟的动态数组)

#include <stdio.h>
#include <stdlib.h>
int main()
{
    int i,n,cc,ff;
    int *people;
    people=(int*)malloc(80*sizeof(int));	//第6和7行等效于int people[80];或int *people=(int*)malloc(80*sizeof(int)); 
    printf("Pleae enter number: ");
    scanf("%d",&n);
    for(i=0;i<n;people[i++]=1);				//先把数组元素全部初始化为1
    for(cc=0,ff=n,i=0;ff!=1;i++)			//ff为要检查的总人数,当ff只剩下最后一个人时,退出for循环 
	{
        if(i==n) i=0;						//如果i越界就把i置为0,实现首尾相接,类似于队列 
        if(people[i])						//如果people[i]元素为1,那就检查下一个数字 
			cc++;							//执行cc++,此时cc为people[i]喊的数字 
        else								//如果people[i]元素为0,那就终止本次循环,执行下一个for循环 
			continue;						
        if(cc==3)							//cc为people[i]喊的数字,若people[i]喊到的数字是3 
		{
            people[i]=0;					//就把people[i]这个元素置为0 
            cc=0;							//把cc置为0,为下一个人喊1做准备			
            ff--;							//要检查的总人数减1 
        }
    }
    for(i=0;i<n;i++)
    {
    	if(people[i])						//people[i]=1标志着这时的people[i]是最后留下来的人,i是序号 
		{
            printf("The number is %d\n", i+1);//由于该动态数组序号从0开始,所以第序号+1个人留下来了 
            break;
        }
	}
    return 0;
}

在VS2019下,需将源文件的scanf改为scanf_s:

#include <stdio.h>
#include <stdlib.h>
int main()
{
    int i, n, cc, ff;
    int* people;
    people = (int*)malloc(80 * sizeof(int));	//第6和7行等效于int people[80];或int *people=(int*)malloc(80*sizeof(int)); 
    printf("Pleae enter number: ");
    scanf_s("%d", &n);
    for (i = 0; i < n; people[i++] = 1);				//先把数组元素全部初始化为1
    for (cc = 0, ff = n, i = 0; ff != 1; i++)			//ff为要检查的总人数,当ff只剩下最后一个人时,退出for循环 
    {
        if (i == n) i = 0;						//如果i越界就把i置为0,实现首尾相接,类似于队列 
        if (people[i])						//如果people[i]元素为1,那就检查下一个数字 
            cc++;							//执行cc++,此时cc为people[i]喊的数字 
        else								//如果people[i]元素为0,那就终止本次循环,执行下一个for循环 
            continue;
        if (cc == 3)							//cc为people[i]喊的数字,若people[i]喊到的数字是3 
        {
            people[i] = 0;					//就把people[i]这个元素置为0 
            cc = 0;							//把cc置为0,为下一个人喊1做准备			
            ff--;							//要检查的总人数减1 
        }
    }
    for (i = 0; i < n; i++)
    {
        if (people[i])						//people[i]=1标志着这时的people[i]是最后留下来的人,i是序号 
        {
            printf("The number is %d\n", i + 1);//由于该动态数组序号从0开始,所以第序号+1个人留下来了 
            break;
        }
    }
    return 0;
}

方法二:(用链表实现)

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

struct Person						//声明结构体
{                                  
    int num;
    struct Person *next;
};

int main()
{ 
	printf("Pleae enter number: ");
	int n;
	scanf("%d",&n);
    struct Person *per=calloc(n,sizeof(struct Person));
    int i;
    
    for (i=0; i<n; i++)
	{                        //此循环给13个人标注序号,1对应第一个人,以此类推,同时实现循环链表,当到达链表最后一个时,地址指向开头。
        per[i].num=i+1;
        if (i==n-1)
			per[i].next=&per[0];
        else
			per[i].next=&per[i+1];
    }
    
    struct Person *p;
    for (p=per, i=0; p->next!=p; p=p->next)	//循环报号,当每次报到第2个人时,p的next指针直接跳过下一个变量,指向下下个变量
    //然后指针p再指向p的next指针所指向变量的地址(此时p的next指针就是之前p的下下个变量所在的地址),当指针p的next指针指向指针p自己时结束for循环。
	{    
        i++;
        if (i%2==0)
		{
            p->next=p->next->next;
            i=0;
        }
    }
    printf("The number is %d\n", p->num);       //输出结果
    return 0;
}

在VS2019下,需将源文件的scanf改为scanf_s:

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

struct Person						//声明结构体
{
    int num;
    struct Person* next;
};

int main()
{
    printf("Pleae enter number: ");
    int n;
    scanf_s("%d", &n);
    struct Person* per = calloc(n, sizeof(struct Person));
    int i;

    for (i = 0; i < n; i++)
    {                        //此循环给13个人标注序号,1对应第一个人,以此类推,同时实现循环链表,当到达链表最后一个时,地址指向开头。
        per[i].num = i + 1;
        if (i == n - 1)
            per[i].next = &per[0];
        else
            per[i].next = &per[i + 1];
    }

    struct Person* p;
    for (p = per, i = 0; p->next != p; p = p->next)	//循环报号,当每次报到第2个人时,p的next指针直接跳过下一个变量,指向下下个变量
    //然后指针p再指向p的next指针所指向变量的地址(此时p的next指针就是之前p的下下个变量所在的地址),当指针p的next指针指向指针p自己时结束for循环。
    {
        i++;
        if (i % 2 == 0)
        {
            p->next = p->next->next;
            i = 0;
        }
    }
    printf("The number is %d\n", p->num);       //输出结果
    return 0;
}