有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号。
用数组模拟环,代码如下:
1 int main() 2 { 3 int n,num; //n为总人数,num为剩余人数。 4 int a[255]={0}; //用0标记此位置有人,若此位置的人退出,则该位置的值为1 5 int i; 6 int flag=0; //flag为报数 7 8 cin>>n; 9 num=n; //剩余人数初始为n 10 11 while(num!=1) //剩余人数为1时,停止循环 12 { 13 for(i=0;i<n;i++) 14 { 15 if(a[i]==0) //若该位置有人,就报数 16 flag++; 17 if(flag==3) //若报数为3,此人退出 18 { 19 flag=0; 20 a[i]=1; 21 num--; 22 } 23 24 } 25 } 26 27 for(i=0;i<n;i++) //遍历数组,第一个值为0的位置处就是剩余的人了 28 { 29 if(a[i]==0) 30 { 31 cout<<"最后一个人的编号是:"<<i<<endl; 32 //数组的序号从0算起,而人的编号从1算起,所以有+1的修正 33 break; 34 } 35 } 36 return 0; 37 }
用循环链表解决,代码如下:
1 class Solution { 2 public: 3 // 循环链表结点结构 4 struct Node 5 { 6 int no; 7 Node* prior,*next; 8 }; 9 int LastRemaining_Solution(int n, int m) 10 { 11 if(n==0||m==0) 12 return -1; 13 Node* first=new Node;// 第一个结点 14 first->no=0; 15 Node* p=first;// 指向新建结点 16 // 创建循环双链表 17 for(int i=1;i<n;i++) 18 { 19 Node* node=new Node; 20 node->no=i; 21 p->next=node; 22 node->prior=p; 23 p=node; 24 } 25 // 构成环 26 p->next=first; 27 first->prior=p; 28 Node* q=first;// 工作指针 29 while(q->next!=q) 30 { 31 int a=m; 32 while(--a) 33 { 34 q=q->next; 35 } 36 // 删除结点,q指向待删除结点 37 Node* qq=q; 38 q->prior->next=q->next; 39 q->next->prior=q->prior; 40 q=q->next; 41 delete qq; 42 } 43 return q->no; 44 } 45 };