nyoj 139 我排第几个【数学】【康托展开】

版权声明:转载请注明出处:http://blog.csdn.net/liu6886 https://blog.csdn.net/liu6886/article/details/50973287

我排第几个

时间限制: 1000 ms  |  内存限制: 65535 KB
难度: 3
描述

现在有"abcdefghijkl”12个字符,将其所有的排列中按字典序排列,给出任意一种排列,说出这个排列在所有的排列中是第几小的?

输入
第一行有一个整数n(0<n<=10000);
随后有n行,每行是一个排列;
输出
输出一个整数m,占一行,m表示排列是第几位;
样例输入
3
abcdefghijkl
hgebkflacdji
gfkedhjblcia
样例输出
1
302715242
260726926


康托展开
康托展开是一个双射,即不仅可以求是第几小,而且可以根据是第几小求出该排列.


Code:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#define INF 0x3f3f3f3f
#define eps 1e-8
#define Si(a) scanf("%d", &a)
#define Sl(a) scanf("%lld", &a)
#define Sf(a) scanf("%lf", &a)
#define Ss(a) scanf("%s", a)
#define Pi(a) printf("%d\n", (a))
#define Pf(a) printf("%.2lf\n", (a))
#define Pl(a) printf("%lld\n", (a))
#define Ps(a) printf("%s\n", (a))
#define W(a) while((a)--)
#define CLR(a, b) memset(a, (b), sizeof(a))
#define LL long long
#define PI acos(-1.0)
const int m = 12;
int main()
{
    int f[m+1];
    f[0] = 1;
    for(int i = 1; i < m; ++i)
    {
        f[i] = f[i-1]*i;
    }
    char s[m+1];
    int t;  Si(t);
    W(t)
    {
        Ss(s);
        int len = strlen(s);
        LL ans = 0;
        for(int i = 0; i < len-1; ++i)
        {
            int sum = 0;
            for(int j = i+1; j <= len-1; ++j)
            {
                if(s[i] > s[j])  ++sum;
            }
            ans += sum * f[len-i-1];
        }
        Pl(ans+1);
    }
    return 0;
}


猜你喜欢

转载自blog.csdn.net/liu6886/article/details/50973287
今日推荐