7-5 jmu-報數游戲 (15 分)


報數游戲是這樣的:有n個人圍成一圈,按順序從1到n編好號。從第一個人開始報數,報到m(m<n)的人退出圈子;下一個人從1開始報數,報到m的人退出圈子。如此下去,直到留下最后一個人。其中n是初始人數;m是游戲規定的退出位次(保證為小於n的正整數)。要求用隊列結構完成。輸出數字間以空格分隔,但結尾不能有多余空格。

輸入樣例:

5 3

輸出樣例:

3 1 5 2 4

輸入樣例:

5 6

輸出樣例:

error!


看到這個題,想到是用STL set來做
下面是最開始的代碼
#include <iostream>
#include<set>
using namespace std;
int main()
{
    set<int> s;
    int m, n;
    cin >> n >> m;
    if (m >= n) {
        cout << "error!";
        return 0;
    }
    for (int i = 0; i < n; i++) {
        s.insert(i + 1);
    }
    set<int>::iterator it;
    it = s.begin();
    int flag = 0;
    while (s.size() != 0) {
        for (int i = 1; i < m; i++) {
            if (!(it != s.end())) {
                it = s.begin();
            }
            it++;
        }
        if (!(it != s.end())) {
            it = s.begin();
        }

        if (flag == 0) {
            cout << *it;
            flag = 1;
        }
        else {
            cout << " " << *it;
        }

        int c = *it;
        s.erase(c);
        int j = 1;
        it = s.find((c + 1) % n);
        if (!(it != s.end())) {
            it = s.begin();
        }
    }
}

測試結果:

 

但是看這一句  it = s.find((c + 1) % n);  假設(c+1)%n在set中沒有找到的話,返回給it的地址就是s.end()  但是假設c+1沒找到后面還有c+2的話就會出錯,所以我手寫了一個測試點,n=8,m=3。

按照題目意思推理得出: 3 6 1 5 2 8 4 7

但是按照我寫的代碼得出的結果是:3 6 1 5 7 8 2 4

所以改進版代碼為:

#include <iostream>
#include<set>
using namespace std;
int main()
{
    set<int> s;
    int m, n;
    cin >> n >> m;
    if (m >= n) {
        cout << "error!";
        return 0;
    }
    for (int i = 0; i < n; i++) {
        s.insert(i+1);
    }
    set<int>::iterator it;
    it = s.begin();
    int flag = 0;
    while (s.size() != 0) {
        for (int i = 1; i < m; i++) {
            if (!(it != s.end())) {
                it = s.begin();
            }
            it++;
        }
        if (!(it != s.end())) {
            it = s.begin();
        }
        
        if (flag == 0) {
            cout << *it;
            flag = 1;
        }
        else {
            cout <<" "<< *it;
        }
            
        int c = *it;
        s.erase(c);
        int j = 1;
        while (1) {
            it = s.find((c + j) % n);
            if (it != s.end())
                break;
            else
                j++;
            if (j == n) {
                break;
                it = s.end();
            }
        }
        
        if (!(it != s.end())) {
            it = s.begin();
        }
    }
}

得出結果:3 6 1 5 2 8 4 7

PTA提交結果:正確

同一個測試點兩種代碼給出的結果是不一樣的,而PTA上提交都是正確的,說明測試點沒有考慮到n遠大於m的情況


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM