1. 程式人生 > 其它 >士兵佇列訓練問題(連結串列練習)

士兵佇列訓練問題(連結串列練習)

技術標籤:杭電OJ

原題連結

Problem Description

某部隊進行新兵佇列訓練,將新兵從一開始按順序依次編號,並排成一行橫隊,訓練的規則如下:從頭開始一至二報數,凡報到二的出列,剩下的向小序號方向靠攏,再從頭開始進行一至三報數,凡報到三的出列,剩下的向小序號方向靠攏,繼續從頭開始進行一至二報數。。。,以後從頭開始輪流進行一至二報數、一至三報數直到剩下的人數不超過三人為止。

Input

本題有多個測試資料組,第一行為組數N,接著為N行新兵人數,新兵人數不超過5000。

Output

共有N行,分別對應輸入的新兵人數,每行輸出剩下的新兵最初的編號,編號之間有一個空格。

Sample Input

2
20
40

Sample Output

1 7 19
1 19 37

分析題意:

  • 將n個數依次按1,2,1,2,1,2… … 標號,然後刪除下標為2的數
  • 再將剩下的數依次按1,2,3,1,2,3… … 標號,然後刪除下標為3的數
  • 迴圈以上兩步

樣例1:
① 把1~20按照1,2,1,2,1,2… …排序,結果如圖:
在這裡插入圖片描述

② 刪除下標為2的數並按照1,2,3,1,2,3… … 排序,結果如圖:
在這裡插入圖片描述
③ 刪除下標為3的數並按照1,2,1,2,1,2…排序,結果如圖:
在這裡插入圖片描述
④ 刪除下標為2的數並按照1,2,3,1,2,3…排序,結果如圖:
在這裡插入圖片描述
⑤ 刪除下標為3的數並按照1,2,1,2…排序,結果如圖:
在這裡插入圖片描述


此時人數不超過三人,故輸出結果1 7 19
注意:

  • erase( it )的作用是刪除迭代器指向的當前元素,並返回該迭代器下一引數的迭代器。寫法:it = li.erase(it);
  • 注意最後一個元素後不能帶空格,格式問題

AC程式碼

#include <cstdio>
#include <list>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

int main()
{
int t;//多組資料 cin >> t; list<int> li;//STL:連結串列 while (t--) { li.clear();//清空上次操作的資料 int n; cin >> n; for (int i = 1;i <= n;i++) li.push_back(i);//輸入1~n個數 int k = 2; list<int>::iterator it; while (li.size() > 3)//連結串列中的元素個數大於3 { int num = 1;//num模擬連結串列中元素的下標1,2,1,2,1,2... ... for (it = li.begin();it != li.end();) { if (num++ % k == 0) { it = li.erase(it);//這句話執行以後會返回下一個迭代器 }else it++; } //若以上for迴圈對2取模,則下一次應該對3取模; //若以上for迴圈對3取模,則下一次應該對2取模; //即k == 2? k = 3:k = 2; if (k == 2) k = 3; else k = 2; } //輸出結果(注意最後一個元素後不能帶空格) for (it = li.begin();it != li.end();it++) { if (it != li.begin()) cout << " "; cout << *it; } cout << endl; } return 0; }

本題需要著重理解以下程式碼如何做到輪流對2和3取模,並且上輪刪除對2取模為0的數,下輪刪除對3取模為0的數

while (li.size() > 3)
        {
            int num = 1;
            
            for (it = li.begin();it != li.end();)
            {
                if (num++ % k == 0)
                {
                    it = li.erase(it);
                }else it++;
            }
            
            if (k == 2) k = 3;
            else k = 2;
        }