zoukankan      html  css  js  c++  java
  • LightOJ1060 nth Permutation(不重复全排列+逆康托展开)

    一年多前遇到差不多的题目http://acm.fafu.edu.cn/problem.php?id=1427

    一开始我还用搜索。。后来那时意外找到一个不重复全排列的计算公式:M!/(N1!*N2!*...*Nn!),

    然后就靠自己YY出解法,搞了好几天,最后向学长要了数据,然后迷迷糊糊调了,终于AC了。

    后来才知道当时想的解法类似于逆康托展开,只是逆康托展开是对于没有重复元素全排列而言,不过有没有重复元素都一个样。

    而现在做这题很顺,因为思路很清晰了,另外这做法和数论DP的统计部分有相似之处。

     1 #include<cstdio>
     2 #include<cstring>
     3 using namespace std;
     4 long long fact[21]={1};
     5 long long calu(int n,int *cnt){
     6     long long res=fact[n];
     7     for(int i=0; i<26; ++i) res/=fact[cnt[i]];
     8     return res;
     9 }
    10 int main(){
    11     for(int i=1; i<21; ++i) fact[i]=fact[i-1]*i;
    12     char str[22];
    13     long long n;
    14     int t;
    15     scanf("%d",&t);
    16     for(int cse=1; cse<=t; ++cse){
    17         scanf("%s%lld",str,&n);
    18         int sn=strlen(str),cnt[26]={0};
    19         for(int i=0; i<sn; ++i) ++cnt[str[i]-'a'];
    20         if(calu(sn,cnt)<n){
    21             printf("Case %d: Impossible
    ",cse);
    22             continue;
    23         }
    24         printf("Case %d: ",cse);
    25         for(int i=0; i<sn; ++i){
    26             for(int j=0; j<26; ++j){
    27                 if(cnt[j]==0) continue;
    28                 --cnt[j];
    29                 if(n>calu(sn-i-1,cnt)){
    30                     n-=calu(sn-i-1,cnt);
    31                     ++cnt[j];
    32                 }else{
    33                     putchar(j+'a');
    34                     break;
    35                 }
    36             }
    37         }
    38         putchar('
    ');
    39     }
    40     return 0;
    41 }
  • 相关阅读:
    jmeter解决乱码
    RedisTemplate方法详解
    linux centos7忘记密码?
    redis config 详解
    Spring Security使用详解(基本用法 )
    Oauth介绍
    springSecurity+Oauth2.0之授权模式(客户端、密码模式)
    springCloud Sleuth分布式请求链路跟踪
    spring cloud Stream消息驱动
    HttpServletResponse
  • 原文地址:https://www.cnblogs.com/WABoss/p/5135911.html
Copyright © 2011-2022 走看看