2 条题解

  • 0
    @ 2024-4-12 20:03:33

    本题正解使用链表解决,但因数据范围优秀,所以可以使用队列暴力解决。

    使用队列主要是方便实现环状顺序表。具体思路是这样的,当队列不空时,一直执行:

    • 将队列前 m1m-1 个元素依次放到队尾;
    • 输出操作后的队首,即第 mm 个元素,然后将其删除。

    AC Code:

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    ll n,m;
    queue<ll> q;
    int main(){
        scanf("%lld%lld",&n,&m);
        for(ll i=1;i<=n;i++) // 将1~n依次放入队列
            q.push(i);
        while(!q.empty()){
            for(ll i=1;i<m;i++)
                q.push(q.front()),q.pop();
            printf("%lld ",q.front()),q.pop();
        }
        return 0;
    }
    
    • 0
      @ 2024-4-12 19:43:49
      #include <iostream>
      #include <vector>
      
      using namespace std;
      
      vector<int> josephus(int n, int m) {
          vector<int> result;
          vector<int> people(n);
      
          for (int i = 0; i < n; i++) {
              people[i] = i + 1;
          }
      
          int idx = 0;
      
          while (!people.empty()) {
              idx = (idx + m - 1) % people.size();
              result.push_back(people[idx]);
              people.erase(people.begin() + idx);
          }
      
          return result;
      }
      
      int main() {
          int n, m;
          cin >> n >> m;
      
          vector<int> ans = josephus(n, m);
      
          for (int i = 0; i < ans.size(); i++) {
              cout << ans[i] << " ";
          }
      
          cout << endl;
      
          return 0;
      }
      

      上述代码定义了一个 josephus 函数,用于解决约瑟夫环问题。在 josephus 函数中,我们首先创建一个大小为 npeople 向量,用于保存每个人的编号。然后,我们使用循环将编号从1到 n 的人依次添加到 people 向量中。

      接下来,我们设置变量 idx 为初始值0,表示从第一个人开始报数。在循环中,我们通过 (idx + m - 1) % people.size() 的计算方式来确定出圈的人的索引。然后,我们将该人的编号添加到结果向量 result 中,并从 people 向量中移除该人。随着每次循环,idx 根据出圈的人进行更新,直到所有的人都出圈。

      最后,在 main 函数中,我们读入输入的 nm 值,并调用 josephus 函数获取出圈人的编号。然后,我们按顺序输出每个出圈人的编号。

      • 1

      信息

      ID
      704
      时间
      1000ms
      内存
      125MiB
      难度
      2
      标签
      递交数
      129
      已通过
      78
      上传者