1 条题解

  • 0
    @ 2026-3-4 14:14:59

    文字教学

    这道题的核心是求当前排列的下M个排列。因为M很小(≤100),直接循环M次,每次求下一个排列即可。

    求下一个排列的步骤:

    1. 从右往左找第一个位置 i,使得 a[i] < a[i+1](找到第一个“下降点”)。
    2. 从右往左找第一个位置 j,使得 a[j] > a[i](找到第一个比 a[i] 大的数)。
    3. 交换 a[i]a[j]
    4. i+1 到末尾的部分反转(让这部分变成最小的排列)。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    
    int a[10005], n, m;
    
    int main() {
        cin >> n >> m;
        for (int i = 0; i < n; ++i) cin >> a[i];
        
        while (m--) {
            // 步骤1:找i
            int i = n - 2;
            while (i >= 0 && a[i] >= a[i + 1]) --i;
            
            // 步骤2:找j
            int j = n - 1;
            while (a[j] <= a[i]) --j;
            
            // 步骤3:交换
            swap(a[i], a[j]);
            
            // 步骤4:反转i+1到末尾
            int l = i + 1, r = n - 1;
            while (l < r) {
                swap(a[l], a[r]);
                ++l; --r;
            }
        }
        
        // 输出
        for (int i = 0; i < n; ++i) {
            if (i) cout << ' ';
            cout << a[i];
        }
        cout << endl;
        return 0;
    }
    
    • 1

    信息

    ID
    88
    时间
    1000ms
    内存
    125MiB
    难度
    3
    标签
    递交数
    3
    已通过
    3
    上传者