您的位置:首页 > 其它

我排第几个

2015-08-31 21:22 405 查看


我排第几个

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

描述

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

输入第一行有一个整数n(0<n<=10000);

随后有n行,每行是一个排列;
输出输出一个整数m,占一行,m表示排列是第几位;
样例输入
3
abcdefghijkl
hgebkflacdji
gfkedhjblcia


样例输出
1
302715242
260726926


来源[苗栋栋]原创
上传者
苗栋栋

思路:

    刚开始根本没思路,所以就想打表找规律,结果根本没办法找。。。最后去看看讨论区,发现原来要用到康托展开公式。

AC代码:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<string>
using namespace std;
typedef long long ll;
string s;
ll sum(int i)
{
ll cnt=0,k=s[i]-'a';
while(++i<12){
if(k>s[i]-'a')cnt++;
}
return cnt;
}
int main()
{
/*freopen("input.txt","r",stdin);*/
int n,i;ll cnt;
int a[15]={39916800,3628800,362880,40320,5040,720,120,24,6,2,1};
cin >> n;
while(n--)
{
cnt=0;
cin >> s;
for(i=0;i<11;++i){
cnt+=sum(i)*a[i];
}
cout << cnt+1 << endl;
}
return 0;
}


优秀代码:

#include<cstdio>
const int Fact[13]={1,1,2,6,24,120,720,5040,40320,362880,3628800,39916800,479001600};
int getTh(char code[],int n)
{
int sum=0;
for(int i=0;i!=n;i++)
{
int rev=0;
for(int j=i+1;j<n;j++)
rev+=(code[i]>code[j]);
sum+=rev*Fact[n-1-i]; //Fact[i]表示i的阶乘。
}
return sum;
}
int main()
{
int n;
char str[15];
scanf("%d",&n);
while(n--)
{
scanf("%s",str);
printf("%d\n",getTh(str,12)+1);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  nyoj