一道算法题-最后留下的是第几号 有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 };