zoukankan      html  css  js  c++  java
  • Lexicography

    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.

        假设字符共有n类,个数分别为m1,m2……,mn,
        那么这个多重集的全排列个数为(m1+m2+……+mn)!/m1!/m2!/……/mn!
        
        然后呢,我们来举个例子,要知道字符集"ICPC"的第12个字符串是多少,
        
        对第一位做出假设
        
        C的话,那么有3!=6种串,
        I的话,有3!/2!=3种串,
        P的话,有3!/2!=3种串,
        
        可知6+3+3=12,那么第一位就是P,从剩下的字符集里找出第12-6-3=3个字符串
        
        现在字符集变成"ICC",
        
        对第二位做出假设
        
        C的话,那么有2!=2种串,
        I的话,有2!/2!=1种串,
        
        可知2+1=3,所以,第二位就是I,从剩下的字符集里找出第3-2=1个字符串
        
        现在字符集变成"CC",
        
        对第三位做出架设
        
        C的话,那么有1!=1种串,
        
        可知1=1,于是,第三位就是C,从剩下的字符集里找出第1-1=0个字符串,
        
        现在字符集变成”C",
        
        这个串并不存在,那么就是直接把剩下的那些字符,就是C补在最后就行了,
        
        很显然,此时剩下的字符集一定都是由某个字符重复组成。

    #include <iostream>
    #include <algorithm>
    #include <string.h>
    #include<stdio.h>
    using namespace std;
    int main()
    {
     char a[20];
     long long int n;
     long long int f[21];
     f[0]=1;
     for(int i=1;i<20;i++)
       f[i]=f[i-1]*i;
    
     while(cin>>a>>n)
     {
    
         if(a[0]=='#'&&n==0)
              break;
             int t=strlen(a);
             int zimu[30];
              memset(zimu,0,sizeof zimu);
          for(int i=0;i<t;i++)
          {
                  zimu[a[i]-'A']++;
    
           }
           for(int i=0;i<t;i++)
           {
             long long int  tot=0;
             for(int j=0;j<26;j++)
             {
                 if(zimu[j])
                 {
                    long long int ppp= f[t-i-1];
                    for(int k=0;k<26;k++)
                    {
                        if(k==j)
                            ppp=ppp/f[zimu[k]-1];
                        else
                            ppp=ppp/f[zimu[k]];
                    }
                    if(tot+ppp>=n)
                    {
                        a[i]=j+'A';
                        n=n-tot;
                        zimu[j]--;
                        break;
                    }
                     else
                     tot=ppp+tot;
                }
    
    
             }
    
    
    
    
           }
          cout<<a<<endl;
    
    
     }
        return 0;
    }
  • 相关阅读:
    Java类的加载及实例的创建
    快速排序--递归法
    个位数统计
    求最长公共字串
    a标签绑定点击事件失败
    js中取el表达式问题
    springmvc json乱码问题
    tomcat发布时候jar包问题
    Mybatis一对一映射resultMap子标签中顺序问题
    spring和springmvc包扫描问题
  • 原文地址:https://www.cnblogs.com/2014slx/p/7262659.html
Copyright © 2011-2022 走看看