数三出局:有n个学生(给学生用数字编号1----n)围在一起做游戏,从第一个学生开始依次数1,2,3;周而复始,数到3的同学从游戏里面淘汰,请打印最后剩下的学生编号

数三出局:有n个学生(给学生用数字编号1----n)围在一起做游戏,从第一个学生开始依次数1,2,3;周而复始,数到3的同学从游戏里面淘汰,请打印最后剩下的学生编号

方案1:给数到3的做标记

#include <stdio.h>
#include <string.h>

void main()
{
	int N;
	scanf("%d",&N);
	
    char student[N];//N个人,1表示未退出,0表示已经退出
    int out[N];//退出的人的号码记录
    int count = 0;//循环计数 0,1,2  
    int num_out = 0;//退出号码记录的数组的下标
	
    memset(student, 1, sizeof(student));//将所有人状态置为1(未退出)
	
	//当num_out=N-1的时候代表退出的数组满了,那就是所有人都退出了,则退出循环
    for (int i = 0; i < N && num_out < N ; i = ++i % N)
    {
        if (1 == student[i] && 2 == count++%3)
        {
            //未退出的人计数到2的人标记退出,并将号码保存到out数组中
            student[i] = 0;
            out[num_out++] = i;
        }
    }

    //循环输出退出的号码
    for (int i = 0; i < N-1; ++i)
    {
        printf("淘汰%d号\n", out[i]+1);
    }
	printf("%d号获胜!\n", out[N-1]+1);
}

方案 2:把数到3的剔除 

#include <stdio.h>

//数三出局
void main()
{
	int count=0;	//循环计数0,1,2
	int n;
	printf("输入总人数:\n");
	scanf("%d",&n);
    char student[n+1];	//N个人+结束符'\0'
	char *p=student;
	
	for(int i=0;i<n;i++)	//编号:1,2,3……n
		student[i]=i+1;
	student[n]=0;	//字符串的结束符'\0',方便统计还剩多少人
	
	while(student[1]!=0)	//只剩1人,则游戏结束
	{
		if(2==count++%3)	//淘汰数到3的同学,计数(0,1,2)对应->报数(1,2,3)
		{
			char *temp=p;
			while(*p!=0)	//剔除p
				*p++=*p;
			
			p=temp-1;	//避免有人不报数
		}
		p++;
		if(*p==0)	//轮到第一位同学报数,指针p指向student首地址
			p=student;
	}
	printf("%d号获胜!\n",*p);
}

一维数组和指针之间的关系
==============================
经典结论:
结论一:数组名出现在表达式中代表该数组首元素的地址
    数组名相当于是个指针,一个指向本数组首元素地址的指针
结论二:
    数组名前面&,表示的是指向整个数组的一个指针(数组指针)

int类型一维数组和指针的关系
    int a[10]={45,89,96,12};
(1)访问数组的方法
第一种:数组名[下标]
    a[1];
第二种: *(数组名+1)
    *(a+1);
第三种:引入单独的指针,指向数组的首元素
    int *p=a; //a等价于&a[0]
    p[0]; //等价于a[0]第一个元素
    p[1]; //等价于a[1]第二个元素
    *(p+2); //等价于a[2]第三个元素
    for(i=0; i<10; i++)
    printf("%d\n",p[i]);
    printf("%d\n",*(p+i));
    printf("%d\n",*(a+i));
    printf("%d\n",a[i]);
(2)两个指针相减
    表示数组中两个指针之间间隔了多少个数据
    注意:经典错误理解成直接用地址值做减法
(3)关于有一维数组名的几种写法(重点理解每种写法的含义)
    a        int *类型的指针
    &a        数组指针  
    a[0]    非指针,数组首元素值
    &a[0]    数组首元素的地址
    a+1        加类型的大小  4个字节
    &a+1    加的是整个数组的大小
    a[0]+1    把a[0]的值加1
    &a[0]+1    加类型的大小  4个字节

char类型一维数组和指针的关系
    char a[10]="hello";
(1)访问数组的方法
第一种:数组名[下标]
    a[1];
第二种: *(数组名+1)
    *(a+1);
第三种:引入单独的指针,指向数组的首元素
    char *p=a; //a等价于&a[0]
    p[0]; //等价于a[0]第一个元素
    p[1]; //等价于a[1]第二个元素
    *(p+2); //等价于a[2]第三个元素
    for(i=0; i<10; i++)
    printf("%c\n",p[i]);
    printf("%c\n",*(p+i));
    printf("%c\n",*(a+i));
    printf("%c\n",a[i]);
(2)两个指针相减
    表示数组中两个指针之间间隔了多少个数据
    注意:经典错误理解成直接用地址值做减法
(3)关于有一维数组名的几种写法(重点理解每种写法的含义)
    a        char *类型的指针
    &a        数组指针  
    a[0]    非指针,数组首元素值
    &a[0]    数组首元素的地址
    a+1        加类型的大小  1个字节
    &a+1    加的是整个数组的大小
    a[0]+1    把a[0]的值加1
    &a[0]+1    加类型的大小  1个字节


版权声明:本文为m0_59014066原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。