Triple Sort (TRPLSRT) - CodeChef May Challenge 2020 Solution

Here s a video solution with an explanation of the code

#include <iostream>
#include <algorithm>
#include <vector>
#include <tuple>
using namespace std;

int n, k;
int nums[200001];
bool visited[200001];

void solve(int t){
    vector<pair<int, int>> doub;
    vector<tuple<int, int, int>> answer;
    
    cin >> n >> k;
    for(int i=0; i<=n; i++){
        cin >> nums[i];
    }
    for(int i=1; i<=n; i++){
        visited[i]=false;
    }
    vector<int> cycle;
    for(int i=1; i<=n; i++){
        if(!visited[i]){
            int j=i;
            while(!visited[j]){
                visited[j]=true;
                cycle.push_back(j);
                j=nums[j];
            }
        }
        while(cycle.size()>2){
            int z=cycle.back();
            cycle.pop_back();
            int y = cycle.back();
            cycle.pop_back();
            int x=cycle.back();
            if(cycle.size()==1){
                cycle.pop_back();
                answer.push_back(tie(x,y,z));
                k--;
            }
        }
        if(cycle.size()==2){
            doub.push_back(make_pair(cycle[0], cycle[1]));
        }
    }
    while(doub.size()>1){
        pair<int, int> one = doub.back();
        doub.pop_back();
        pair<int, int> two = doub.back();
        doub.pop_back();
        answer.push_back(tie(one.second, two.first, two.second));
        answer.push_back(tie(one.first, one.second, two.first));
        k-=2;
    }
    if(!doub.empty()){
        cout << "-1" << endl;
    }
    if(k>=0){
        cout << answer.size() << endl;
        for(int i=0; i<answer.size(); i++){
            cout << get<0>(answer[i]) << " " << get<1>(answer[i]) << " " << get<2>(answer[i]) << endl;
        }
    }
    return;
}

int main(){
    int tests;
    cin >> tests;
    for(int i=0; i<tests; i++){
        solve(i);
    }
    return 0;
}
3 Likes

This does not even pass subtask 1.
The first and most obvious bug is when you check cycle.size() == 1.
There should NOT be a curly braces “{ }” after that because as the code is now the “answer.push_back” will not execute unless cycle size is 1.

1 Like

change this to

if(cycle.size()==1)
                cycle.pop_back();
answer.push_back(tie(x,y,z));
k--;

should work. When you have permutation like a->b->c->d->e->a , you shift(c->d->e->c) and permutation becomes (a->b->e->a). You need to pop third element of cycle only when it is the last triplet, else you are considering that all cycles are either of length 3 or 2.

can anybody explain why the above method works.
I got how to do it but why to do it??

It’s does not even pass subtask 1.

It’s a WRONG SOLUTION !!!