Tuesday, 3 May 2016

1060 - nth Permutation

1060 - nth Permutation

Given a string of characters, we can permute the individual characters to make new strings. At first we order the string into alphabetical order. Then we start permuting it.
For example the string 'abba' gives rise to the following 6 distinct permutations in alphabetical order.
aabb 1
abab 2
abba 3
baab 4
baba 5
bbaa 6
Given a string, you have to find the nth permutation for that string. For the above case 'aabb' is the 1st and 'baab' is the 4th permutation.

Input

Input starts with an integer T (≤ 200), denoting the number of test cases.
Each case contains a non empty string of lowercase letters with length no more than 20 and an integer n (0 < n < 231).

Output

For each case, output the case number and the nth permutation. If the nth permutation doesn't exist print 'Impossible'.

Sample Input

Output for Sample Input

3
aabb 1
aabb 6
aabb 7
Case 1: aabb
Case 2: bbaa
Case 3: Impossible


-----------------------------------------------EDITORIAL ---------------------------------
 THIS PROBLEM CAN BE SOLVED RECURSIVELY ..
  FIRST  OF ALL WE CHECK MAXIMUM NUMBER OF PERMUTATIONS POSSIBLE FROM THE  GIVEN STRING ... IF IT IS < N THAN ANS IS IMPOSSIBLE , ELSE

NOW WE HAVE TO FIX  CHARACTER AT EACH POSITION STARTING FROM MSB POSITION ,


FOR FIXING THE CHARACTER AT ANY POSITION INITIALLY WE TRY TO FIX SMALLEST CHARACTER AT THAT POSITION IF BY PLACING THAT CHARACTER NUMBER OF PERMUTATION FORMED >=  REMAINING REQUIRED   PERMUTATION THAN FIX THIS CHARTER AT THAT POSITION , AND DECREASE THE FREQUENCY OF THIS CHARACTER SINCE THIS CHARACTER  IS USED AT THIS POSITION AND MOVE TO NEXT POSITION , ELSE IF NO OF PERMUTATION FORMED BY PLACING THIS CHARACTER IS LESS THAN THE REQUIRED REMAINING PERMUTATION THAN DECREASE REMAINING PERMUTATION   BY THE NUMBER OF PERMUTATION FORMED BY PLACING THIS CHARACTER AT THAT POSITION ( SINCE  THIS COUNT TIMES NUMBER OF PERMUTATIONS COMES IN BETWEEN CURRENT TO FINAL PERMUTATION ) AND TRY TO FIND NEXT CHARACTER FOR THIS POSITION,.....

SEE THE CODE FOR CLARITY 

----------------------------------------CODE-------------------------------------------------------
#include<bits/stdc++.h>
using namespace std;
typedef long long int lli;
string s,build;
int cnt[30];
lli  ncr[25][25];
int len;

// return number of  permutation possible from given n number of characters 
lli count(int n)
 {
    lli ret = 1;
    
    for (int i = 0; i < 26; i++) 
{
        ret *= ncr[n][cnt[i]];
        n -= cnt[i];
   
    }
    return ret;
}



int solve(int cur_pos,int rem_perm)
 {
  if(cur_pos>len)
    {
      printf("\n");
      return 0;
  }
  else
   {
    int i;
       for( i=0;i<=25;i++)
        {
          if(cnt[i])
           {
             cnt[i]--;
             lli use=count(len-cur_pos);
              if(use>=rem_perm) 
                                 {
                                //  if by fixing this character at current position permutation will >= remaining
                               //  k than  we can  use this character at this position
              break;
                                   }
                          

               cnt[i]++;//  since we are not using  i as the character at curent_pos so again                                          //increase its count
                rem_perm-=use;//  decrease number of remaining  perm 
  }
   }
    printf("%c",(char)(i+'a'));
    solve(cur_pos+1,rem_perm);
   }
 }




int main()
 {
 
  int t;
  int cas=1;
  for(int i=0;i<=20;i++)
   {
     ncr[i][0]=1;
     ncr[i][i]=1;
     for(int j=1;j<i;j++)
      {
       ncr[i][j]=ncr[i-1][j]+ncr[i-1][j-1];
}
  }

  
  scanf("%d",&t);
  while(t--)
   {
    int n;
     cin>>s>>n;
   
    memset(cnt,0,sizeof cnt);
     len=s.length();
     for(int i=0;i<len;i++)
        {
       cnt[s[i]-'a']++;
   }
    if(count(len)<n)
    {
     printf("Case %d: ",cas++);
     printf("Impossible\n");
}
        
        else
          {
           printf("Case %d: ",cas++);
          solve(1,n);
            
  }
  }
 
 }

No comments:

Post a Comment