比大小

比大小

题目描述 								现在有"abcdefghijkl”12个字符,将其所有的排列中按字典序排列,给出任意一种排列,说出这个排列在所有的排列中是第几小的? 							
输入第一行有一个整数n(0<n<=10000);随后有n行,每行是一个排列; 样例输入3abcdefghijklhgebkflacdjigfkedhjblcia
输出输出一个整数m,占一行,m表示排列是第几位; 样例输出1302715242260726926
时间限制C/C++语言:2000MS其它语言:4000MS 内存限制C/C++语言:65536KB其它语言:589824KB

本题使用康托展开:

这个展开怎么理解呢?我们每一位计算的都是前面和本数字一样、本位比本数字小的数字个数。就拿1324做例子,第一位1因为没有比1小的,所以是0;而第二位3,我们实际计算的是第一位也是1、但是第二位比3小的数字个数,因为1已经用过了,所以这一位只能是2,所以是1*2!这个2是因为接下来还有两位,根据全排列计算出来的情况总数。正是因为这样的计算方法,每次计算的情况才没有重复,才能加和。


import java.util.Arrays;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        int n=sc.nextInt();
        int[]used=new int[12];
        long[]mut=new long[12];
        //先把阶乘计算出来
        for(int i=1;i<12;i++){
            long ans=1;
            for(int j=1;j<=i;j++){
                ans*=j;
            }
            mut[i]=ans;
        }
        for(int i=0;i<n;i++){
            Arrays.fill(used,0);
            long ans=0;
            String string=sc.next();
            //从头到尾,一个字符一个字符地分析
            for(int j=0;j<12;j++){
                int c=string.charAt(j)-'a';
                used[c]=1;
                int count=0;
                for(int k=0;k<c;k++){
                    //count是计算有几个比当前字符小的字符还没有使用
                    if(used[k]==0){
                        count++;
                    }
                }
                //阶乘只和位置有关
                ans+=count*mut[11-j];
            }
            //输出从1开始,所以要加1
            System.out.println(ans+1);
        }
    }
}
posted @ 2020-03-22 16:36  别再闹了  阅读(469)  评论(0)    收藏  举报