zoukankan      html  css  js  c++  java
  • Lexicography(数学推论>>求按字典序排第k个排列)

    Lexicography
    Time Limit:1000MS     Memory Limit:131072KB     64bit IO Format:%lld & %llu

    Description

    An anagram of a string is any string that can be formed using the same letters as the original. (We consider the original string an anagram of itself as well.) For example, the string ACM has the following 6 anagrams, as given in alphabetical order:

    ACM AMC CAM CMA MAC MCA As another example, the string ICPC has the following 12 anagrams (in alphabetical order):

    CCIP CCPI CICP CIPC CPCI CPIC ICCP ICPC IPCC PCCI PCIC PICC Given a string and a rank K, you are to determine the Kth such anagram according to alphabetical order.

    Input

    Each test case will be designated on a single line containing the original word followed by the desired rank K. Words will use uppercase letters (i.e., A through Z) and will have length at most 16. The value of K will be in the range from 1 to the number of distinct anagrams of the given word. A line of the form "# 0" designates the end of the input.

    Output

    For each test, display the Kth anagram of the original string.

    Sample Input

    ACM 5
    ICPC 12
    REGION 274
    # 0

    Sample Output

    MAC
    PICC
    IGNORE

    Hint

    The value of K could be almost 245 in the largest tests, so you should use type long in Java, or type long long in C++ to store K.

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<algorithm>
     4 typedef long long ll ;
     5 char a[20] ;
     6 int alp[30] ;
     7 char map[20] ;
     8 bool vis[30] ;
     9 ll k ;
    10 int n ;
    11 
    12 ll fact (int n)
    13 {
    14     ll sum = 1 ;
    15     for (int i = 1 ; i <= n ; i ++) {
    16         sum *= 1ll * i ;
    17     }
    18     return sum ;
    19 }
    20 
    21 ll calc (int x)
    22 {
    23     int cnt = 0 ;
    24     for (int i = 0 ; i < n ; i++) {
    25         if (!vis[i]) cnt ++ ;
    26     }
    27     ll sum = 1 ;
    28     for (int i = 0 ; i < 26; i++) {
    29         if (i + 'A' == a[x]) {
    30             if ( alp[i] - 1 > 1)  sum *=  fact (alp[i] - 1) ;
    31         }
    32         else {
    33             if (alp[i] > 1) sum *=  fact (alp[i]) ;
    34         }
    35     }
    36   //  printf ("cnt=%d, sum=%lld
    " , cnt , sum ) ;
    37     return fact (cnt - 1) / sum ;
    38 }
    39 
    40 void dfs (int deep)
    41 {
    42     if (deep == n) return ;
    43     for (int i = 0 ; i < n;  i ++) {
    44      //   printf ("deep=%d,%c
    " , deep , a[i]) ;
    45         if (!vis[i] ) {
    46                 if (k - calc (i) > 0) {
    47                    // printf ("%c , k=%lld , fact=%lld
    " , a[i] , k , calc (i)) ;
    48                     k -= calc ( i ) ;
    49                 }
    50                 else {
    51                     if (k == 1) {
    52 
    53                     }
    54                     vis[i] = 1 ;
    55                     alp[a[i] - 'A'] -- ;
    56                     map[deep] = a[i] ;
    57                 //    printf ("k=%d
    " , k ) ;
    58              //       printf ("deep=%d , %c
    " , deep , map[deep]) ;
    59                     dfs (deep + 1) ;
    60                     return ;
    61                 }
    62                 while (a[i + 1] == a[i])  i ++ ;
    63         }
    64     }
    65 }
    66 
    67 int main ()
    68 {
    69    // freopen ("a.txt" , "r" , stdin ) ;
    70     while (scanf ("%s" , a) != NULL) {
    71         scanf ("%lld" , &k) ;
    72         if (a[0] == '#' && k == 0) break ;
    73         memset (alp , 0 , sizeof(alp)) ;
    74         for (int i = 0 ; a[i] != '' ; i ++) {
    75             alp[a[i] - 'A'] ++ ;
    76         }
    77         n = strlen (a) ;
    78         std::sort (a , a + n ) ;
    79      /*   for (int i = 0 ; i < n ; i++) {
    80             printf ("%c" , a[i]) ;
    81         } puts ("") ;*/
    82         dfs (0) ;
    83         memset (vis , 0 , sizeof(vis)) ;
    84         for (int i = 0 ; i < n ; i ++) printf ("%c" , map[i]) ; puts ("") ;
    85     }
    86     return 0 ;
    87 }
    View Code
  • 相关阅读:
    linux常用指令
    Can't create session svn: Unable to connect to a repository at URL “...”的解决方案
    Web前端之iframe详解
    html和js实现滚动条效果
    升级API证书(权威CA颁发)
    公众号生成带推荐码(场景id)的二维码
    小程序生成带推荐码(场景id)的二维码
    MySQL TEXT数据类型的最大长度
    微信退款全款退,退一部分,分开退一次以上区别跳坑[订单金额或退款金额与之前请求不一致]
    php RSA公钥私钥加解密和验证用法
  • 原文地址:https://www.cnblogs.com/get-an-AC-everyday/p/4445229.html
Copyright © 2011-2022 走看看