• 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的情况

  • 相关阅读:
    限制泛型可用类型
    泛型的常规用法(声明两个类型)
    一个类似于金字塔的图形
    Fibonacci数
    快来秒杀我
    奇偶数分离
    Background
    Financial Management
    HangOver
    Binary String Matching
  • 原文地址:https://www.cnblogs.com/haijie-wrangler/p/10732388.html
Copyright © 2020-2023  润新知