Submission #1365105

#TimeUsernameProblemLanguageResultExecution timeMemory
1365105shahaprogA String Problem (EGOI25_stringproblem)C++20
50 / 100
26 ms10196 KiB
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
using namespace std;
using namespace __gnu_pbds;
template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
template <typename T>
using ordered_multiset = tree<T, null_type, less_equal<T>, rb_tree_tag, tree_order_statistics_node_update>;

#define int long long
#define Shahriyor ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define vi vector<int>
#define vvi vector<vi>
#define vvvi vector<vvi> 
#define vc vector<char>
#define vs vector<string>
#define vp vector<pair<int,int>>
#define vvp vector<vector<pair<int,int>>>
#define all(x) (x).begin(), (x).end()
#define allr(x) x.rbegin(), x.rend()
#define sz(x) (int)x.size()
#define endl '\n'
#define len(a) (int)(a).length()
#define inf 4e18
#define print(x) { cout << x << endl; return; }

void Solve();
int mod = 1e9+7;
int LOG = 20;
vi dx = {-1, 1, 0, 0, 1, -1, 1, -1};
vi dy = {0, 0, 1, -1, 1, -1, -1, 1};

ostream& operator<<(ostream& out, vi& a) {
    for(int i=0;i<sz(a);i++) out << a[i] << ' ';
    return out;
}
istream& operator>>(istream& in, vi& a) {
    for(int i=0;i<sz(a);i++) in >> a[i];
    return in;
}
int sum(vi& l) {return accumulate(all(l),(int)0);}
int binpow(int a, int b){
    int res = 1;
    while(b){
        if(b & 1) res = res * a % mod;
        a = a * a % mod;
        b >>= 1;
    }
    return res;
}
signed main(){
    clock_t start = clock();
    Shahriyor;
    int t = 1;
    // cin >> t;
    while(t--) Solve();
    // cerr << "Time: " << double(clock() - start) / double(CLOCKS_PER_SEC) * 1000 << " ms\n";
}

void Solve(){
    int n; cin >> n;

    vector<pair<int,int>> cur(n);
    vector<int> cnt(2*n, 0);

    for(int i = 0; i < n; i++){
        cin >> cur[i].first >> cur[i].second;
        cnt[(cur[i].first + cur[i].second) % (2*n)]++;
    }

    // choose best target (only odd ones)
    int mx = 0, t = -1;
    for(int i = 1; i < 2*n; i += 2){
        if(cnt[i] > mx){
            mx = cnt[i];
            t = i;
        }
    }

    // edge case: no odd rotation present
    if(t == -1){
        t = 1;
        mx = 0;
    }

    cout << n - mx << endl;

    // pin -> string mapping
    vector<int> pin_to_string(2*n, -1);
    for(int i = 0; i < n; i++){
        pin_to_string[cur[i].first] = i;
        pin_to_string[cur[i].second] = i;
    }

    vector<int> good(n, 0);
    for(int i = 0; i < n; i++){
        if((cur[i].first + cur[i].second) % (2*n) == t){
            good[i] = 1;
        }
    }

    vector<array<int,3>> ops;

    for(int i = 0; i < n; i++){
        if(good[i]) continue;

        int p = i;

        while(true){
            int a = cur[p].first;
            int b = cur[p].second;

            int need = (t - a + 2*n) % (2*n);

            if(need == b){
                good[p] = 1;
                break;
            }

            int q = pin_to_string[need];

            // move b -> need
            ops.push_back({p, b, need});

            // update pin ownership
            pin_to_string[b] = -1;
            pin_to_string[need] = p;

            // update string
            if(cur[p].first == b) cur[p].first = need;
            else cur[p].second = need;

            good[p] = 1;

            if(q == p || good[q]) break;

            p = q;
        }
    }

    for(auto &op : ops){
        cout << op[0] << " " << op[1] << " " << op[2] << endl;
    }
}

// Code once, never "guess", have clear plan.
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...