有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;
}