解题思路:
很多学生会采用数组的方法,用0或1代表是否被淘汰,这种解法有其优点,就是简单,代码比较少,但是缺点也很大,比如

不能充分利用数组空间,容易造成数组越界,或者算法效率低下等等,并且也不是题目的本意,当然,以解决问题为主,其实什么方法都行。这里的建议用单链表,可以克服以上的缺点,并且这也是这道题最官方的解法。


参考代码:

#include<stdio.h>

#include<malloc.h>

#include<assert.h>//断言

typedef struct SList

{

int data;

struct SList *next;  //data域存放这个人的序号,当然原始序号


}Node;

void Initial(Node **head);

void push_back(Node **head,int x);  //插入节点,就是人就坐


int main()

{

int i;

int n;

Node *head;

Initial(&head); //头节点的data域表示人的个数,当剩下一个人的时候,游戏结束


scanf("%d",&n);

for(i=1;i<=n;i++)

{

push_back(&head,i);  //要修改一级指针的值,是不是得传他的地址过去?

}


i=0;

Node *p=head->next;

while(++i)

{

if(head->data==1)

{

printf("%d\n",p->data);

break;

}

if(i%3==0) //如果是3的倍数,也就是题目中的数到3,这个人得离开

{

Node *q=p->next;

p->data=q->data;  

p->next=q->next;

free(q);

head->data--;  //相应的人数减少一个

continue;

}

p=p->next;   //如果数到1和2,那么接着往下数

}

return(1);

}


void Initial(Node **head)

{

(*head)=(Node*)malloc(sizeof(Node));

assert((*head)!=NULL);


(*head)->data=0;

(*head)->next=*head;


return;

}


void push_back(Node **head,int x)

{

Node *s=(Node*)malloc(sizeof(Node));

assert(s!=NULL);

    s->data=x;

s->next=NULL;


if((*head)->data==0)  //构建链表,使得尾节点和第一节点连接起来,节点代表人,头尾相接表示坐成一圈

{

(*head)->next=s;

s->next=s;

}

else

{

Node *p=(*head)->next;

while(p->next!=(*head)->next)

p=p->next;

s->next=p->next;

p->next=s;

}

(*head)->data++;

}


点赞(1)
 

0.0分

0 人评分

C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:

一点编程也不会写的:零基础C语言学练课程

解决困扰你多年的C语言疑难杂症特性的C语言进阶课程

从零到写出一个爬虫的Python编程课程

只会语法写不出代码?手把手带你写100个编程真题的编程百练课程

信息学奥赛或C++选手的 必学C++课程

蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程

手把手讲解近五年真题的蓝桥杯辅导课程

评论列表 共有 0 条评论

暂无评论