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
  • 相关阅读:
    再学 GDI+[91]: TGPImage(11) 转灰度图像
    再学 GDI+[90]: TGPImage(10) 获取图像的调色板信息
    给 Memo 排序的函数
    再学 GDI+[97]: TGPImage(17) 获取 GDI+ 所支持的可编码、可解码的图像格式
    再学 GDI+[94]: TGPImage(14) 增减图像的红、绿、蓝三色的成分
    上周热点回顾(10.2611.1)
    博客园上海俱乐部Windows 7社区发布活动的奖品
    顶吧!顶出今日头条
    博客园电子期刊2009年10月刊发布啦
    对于近期社区问题的一点想法
  • 原文地址:https://www.cnblogs.com/get-an-AC-everyday/p/4445229.html
Copyright © 2011-2022 走看看