DMOJ · dmopc21c10p2

Cycle Sort

This C++ solution uses simulation for DMOJ dmopc21c10p2 Cycle Sort. Read the reasoning, inspect the code, or try your own test case below.

dmopc21c10p2Sorting & searchingSimulationC++68 lines
Solution068of 248
Open official problem ↗ Download C++ file ↓ Search the library → Open full Code Lab ↗ Report an issue ↗

Approach

Simulation

Cycle Sort permits a cyclic shift and at most one swap to minimize a permutation; the code constructs the required lexicographically smallest result.

Sorting & searching

Problem and code

Useful links.

Written by benbenyaojifen. Try the problem first, then compare your approach with the code.

Open official problem ↗View exact source file ↗
Implementation

cycle_sort.cpp

C++

    #include <bits/stdc++.h>
    using namespace std;
     
    int n;
    vector<int> arr;
     
    // put the right numbers after 1
    vector<int> solve1(vector<int> a) {
        a.insert(a.end(), a.begin(), a.end());
        int idx1 = find(a.begin(), a.end(), 1) - a.begin();
        vector<int> b(a.begin() + idx1, a.end());
        for (int i = 0; i < n; i++) {
            if (b[i] != i + 1) {
                int miss = find(b.begin(), b.end(), i + 1) - b.begin();
                swap(b[i], b[miss]);
                break;
            }
        }
        b.resize(n);
        return b;
    }
     
    // move the 1 in front of the 2
    vector<int> solve2(vector<int> a) {
        int pos2 = find(a.begin(), a.end(), 2) - a.begin();
        int pos1 = find(a.begin(), a.end(), 1) - a.begin();
        // swap 1 into the slot just before 2
        swap(a[(pos2 - 1 + n) % n], a[pos1]);
        // rotate so that 1 is at front
        int start = find(a.begin(), a.end(), 1) - a.begin();
        vector<int> b;
        b.reserve(n);
        for (int i = 0; i < n; i++)
            b.push_back(a[(start + i) % n]);
        return b;
    }
    // if 1 is already right after 2, just swap them
    vector<int> solve3(vector<int> a) {
        int pos2 = find(a.begin(), a.end(), 2) - a.begin();
        vector<int> b(n);
        for (int i = 0; i < n; i++)
            b[i] = a[(pos2 + i) % n];
        if (b[1] == 1)
            swap(b[0], b[1]);
        return b;
    }
     
    int main() {
        ios::sync_with_stdio(0);
        cin.tie(0);
        cin >> n;
        arr.resize(n);
        for (int i = 0; i < n; i++)
            cin >> arr[i];
        if (n == 1) {
            cout << "1" << "\n";
            return 0;
        }
        auto a1 = solve1(arr);
        auto a2 = solve2(arr);
        auto a3 = solve3(arr);
        // pick lexicographically smallest
        vector<int> ans = min(min(a1, a2), a3);
        for (int i = 0; i < n; i++)
            cout << ans[i] << (i + 1 == n ? '\n' : ' ');
        return 0;
    }
     
        

Did this explanation save you time? I'm a Grade 11 student building this free library to make difficult algorithms easier to understand.

Buy me a coffee ↗Keep studying →

Test this problem

Run your code here.

Paste your code, run a test case, compare the output, or trace selected values.

Full trace, comparison & stress testing ↗
StatusReady
Output
No run yet.
Diagnostics
No diagnostics yet.

Each run is isolated and has strict limits. Passing one test does not guarantee the judge will accept the solution.