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
  • 相关阅读:
    学习进度条
    软件工程期末总结
    实验四 主存空间的分配与回收
    学术诚信与道德
    《构建之法》第八、九、十章读后感
    实验三、进程调度模拟程序实验
    《构建之法》第六七章读后感
    Scrum团队成立3.0
    0428-项目再开发2.0
    作业调度模拟程序
  • 原文地址:https://www.cnblogs.com/get-an-AC-everyday/p/4445229.html
Copyright © 2011-2022 走看看