本文共 1708 字,大约阅读时间需要 5 分钟。
问题描述已知n个人(以编号1,2,3…n分别表示)围坐在一张圆桌周围。从编号为1的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。要求输出最后一位出列的人的序号。
一般来说是41个人,报到3出列 思考过程当我遍历整个序列到尾部的时候,我需要把指针重新指向整个序列的头部。如果用数组来做做,只需要令k=(k+1)%len就能实现序列的循环。这里我们利用一种数据结构–>单向循环链表来做。虽说思想比较简单,但是基本涵盖了链表的基本知识。 还是建议(包括我自己)不要去网络上找代码,一定要回到书本,网上部分人的代码是错误的或者说思路比较清奇,对于基础知识不牢靠的同学来说是一种致命打击 下面给出代码#include#include //定义结构体 typedef struct Node{ int num;//这里存的是每个人最初的序号 struct Node *next; }Node,*PNode;//初始化链表 void init(int n,PNode &head){ head = (PNode)malloc(sizeof(Node)); head->num=1;//头插法 /* PNode temp; head->num = 1; head->next=head; for(int i=n;i>=2;i--){//给每个人一个序号 temp=(PNode)malloc(sizeof(Node)); temp->num = i; temp->next = head->next; head->next = temp; } *///尾插法 PNode tail=head; PNode p; for(int i=2;i<=n;i++){ p = (PNode)malloc(sizeof(Node)); p->num = i; p->next=head; tail->next = p; tail=p; } }//删除节点void deleteNode(PNode &p){ PNode temp = p->next; p->next = p->next->next; free(temp);} void write(PNode head){ PNode p = head; while(p->next!=head){ printf("%d ",p->num); p=p->next; } printf("%d ",p->num);}int getlen(PNode head){ int len = 1; PNode p = head; while(p->next!=head){ len++; p=p->next; } return len;}int main(){ int n,m;//n为总人数,m为需出列的序号 scanf("%d%d",&n,&m); PNode p; init(n,p); //初始化单向需循环链表 printf("总人数为:%d\n",getlen(p)); PNode head=p; //用来遍历链表 int count=0;//用来标记序号 while(n>2){ count++;// 0 41 69 88 101 110 116 119 120 if((count+1)%m==0){ //定位到要删除节点的前驱 printf("%d ",head->next->num); deleteNode(head); n--; count++; } head=head->next; } printf("\n"); //**不能使用p指针,实际上p指针很可能在运算过程中丢失了** printf("剩余人数为%d\n",getlen(head)); write(head);return 0;}
转载地址:http://jrqen.baihongyu.com/