10 September 2016

Absolute Permutation

Standard
This is the most efficient solution of the Absolute Permutation question asked
at hackerrank.com .
Here is the question.
We define  to be a permutation of the first  natural numbers in the range . Let  denote the position of  in permutation  (please use -based indexing).
 is considered to be an absolute permutation if  holds true for every .
Given  and , print the lexicographically smallest absolute permutation, ; if no absolute permutation exists, print -1.
Input Format
The first line of input contains a single integer, , denoting the number of test cases. 
Each of the  subsequent lines contains  space-separated integers describing the respective  and  values for a test case.
Constraints
Output Format
On a new line for each test case, print the lexicographically smallest absolute permutation; if no absolute permutation exists, print -1.
Key observations.
  1. The value of  k should be less than  or equal to n/2 other wise abs(pos¡  -i) =k  will not hold true for every i.
  2. K should be a divisor of n (i.e.n%k=0) .Take a pen and a paper and experiment with different k (divisor and non-divisor of n). It's better for you if you try it yourself.
  3. The quotient of n/k should be divisible by 2. (i.e. (n/k)%2=0) Again think!!
If you still didn't get this than a detailed explanation is there at the end of this post.I have not given the full explanation here since i want you all to try with these hint's first.
That's it . That was all the hidden tricks that was there in this problem.
Here is my code.
#include <iostream>
#include <vector>
using namespace std;
int main(){
                 int t,n,k,dev;
                 cin >> t;
for(int a0 = 0; a0 < t; a0++){
           cin >> n >> k;
           dev=n/k;
            vector<int> pos(n);
            if(k==0){      //if k=0 print the array itself without manipulating any thing
                            for(int i=1;i<=n;i++)cout<<i<<" ";
            }
           else if ((k<=n/2)&&(n%k==0)&&(dev%2 ==0)){   //else if k<=n/2 and n%k==0 and (n/k)%2==0 than do this
                         for(int i=0;i<n;i++){
                                   if((i/k)%2 == 0) pos[i] = i + k+1;  
                                  else   pos[i] = i - k+1;
                          }
                          for (int i = 0; i< n; i++)  cout << pos[i] << " ";
            }
            else   cout << "-1";
            cout <<endl;
}
return 0;
}

Here is the complete explanation in case someone is still struggling.
Note: k<=n/2 is very apparent so I have not discussed that here.
Please forgive me for explaining this in paper since I don't have enough time to type it in my computer.

*****
IF YOU WANT ME TO EXPLAIN A PERTICULAR PROBLEM THAN PLEASE LEAVE A LINK TO THE PROBLEM IN THE COMMENT SECTION
*****

4 comments:

  1. Sir, could you please explain this one:
    https://www.hackerrank.com/challenges/almost-sorted

    ReplyDelete
  2. Hi,

    Thanks for your hint. I was able to solve the problem.
    Here is the most efficient solution in Java.

    static int[] absolutePermutation(int n, int k) {

    LinkedList linkedIndexes = new LinkedList();
    int[] permutation = new int[n];
    if(k>0 && k <= n/2 && (n%k == 0) && (n/k)%2 == 0) {
    boolean add = true;
    if(k == 1){
    add = false;
    }
    for(int i=1;i<=n;i++) {
    if((k == 1) || (i > 1 && (i-1)%k == 0)) {
    if(add) {
    add = false;
    }
    else {
    add = true;
    }
    }
    if(add) {
    permutation[i-1] = i+k;
    }
    else {
    permutation[i-1] = Math.abs(i - k);
    }
    }
    }
    else if(k == 0){
    for(int i=1;i<=n;i++){
    permutation[i-1] = i;
    }
    }
    else {
    permutation = new int[1];
    permutation[0] = -1;
    }
    return permutation;
    }

    ReplyDelete