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
  • 相关阅读:
    Windows快捷方式的形式关机方法
    [Andriod官方训练教程]创建你的第一个App之创建一个简单的用户界面
    使用GDAL对HDF数据进行geoloc校正
    破解sqlyog 30天试用限制
    [Andriod官方训练教程]创建你的第一个App之运行你的App
    [Andriod官方训练教程]创建你的第一个App之开始另一个Activity
    GDAL对空间数据的管理
    win linux 下 部署war包到Tomcat根目录
    Spring session
    使用GDAL对HDF数据进行校正
  • 原文地址:https://www.cnblogs.com/get-an-AC-everyday/p/4445229.html
Copyright © 2011-2022 走看看