数三出局:有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个字节