您的位置:首页 > 其它

【ACM】nyoj_143_第几是谁_201308071558

2013-08-07 16:24 274 查看
第几是谁?
时间限制:3000 ms | 内存限制:65535 KB
难度:3
描述
现在有"abcdefghijkl”12个字符,将其按字典序排列,如果给出任意一种排列,我们能说出这个排列在所有的排列中是第几小的。但是现在我们给出它是第几小,需要你求出它所代表的序列.
输入
第一行有一个整数n(0<n<=10000);
随后有n行,每行是一个整数m,它代表着序列的第几小;
输出
输出一个序列,占一行,代表着第m小的序列。
样例输入
3
1
302715242
260726926

样例输出
abcdefghijkl
hgebkflacdji
gfkedhjblcia

#include <stdio.h>
#define LEN 12
int JC(int n)
{
int i,sum=1;
for(i=1;i<=n;i++)
sum*=i;
return sum;
}
int main()
{
int N;
scanf("%d",&N);
while(N--)
{
int i,j,k,t,m;
char str[]="abcdefghijkl";
char a[15];
scanf("%d",&m);
m-=1;
for(i=0;i<LEN;i++)
{
t=m/JC(LEN-i-1);
for(j=0;j<LEN;j++)
{
if(str[j]!='0')//判断str[j]是否用过,与下面 str[j]='0';对应
{
if(t==0)
break; //如果t=0,结束内循环
t--; //此语句作用很大 如果刚开始 T=6 for循环的作用就是:让a[j]不断的向后移动并跳过已经出现过的字母 很强大。
}
}
a[i]=str[j];
str[j]='0'; //标记,表示这个字母已经使用过
m%=JC(LEN-i-1);
}
a[12]='\0';
printf("%s\n",a);
}
return 0;
}

//参考代码如下:
/*
#include"stdio.h"
#include"stdlib.h"
int main()
{
int fac[]={1,1,2,6,24,120,720,5040,40320,362880,3628800,39916800,479001600};//矩阵表
int n=12,k,i,j,t,m;
char s[14];//存放序列
scanf("%d",&m);

while(m--)
{
char a[13]="abcdefghijkl";//字母列表
scanf("%d",&k);
k=k-1;
for(i=0;i<n;i++)//进行12次循环
{
t=k/fac[n-i-1];//求出T是一个数

for(j=0;j<n;j++)
if(a[j]!='0')//与下句的a[j]='0',相呼应,检验是否该字母已经被用过。
{
if(t==0) break;//t为0 就直接跳出最内层的循环
t--; //此语句作用很大 如果刚开始T=6 for循环的作用就是:让a[j]不断的向后移动并跳过已经出现过的字母 很强大。
}
s[i]=a[j];
a[j]='0';//此语句起标记作用,标记字母标中的该字母已经用过。

k%=fac[n-i-1];
}
s[12]='\0';
printf("%s\n",s);
}
system("pause");
return 0;
}
*/

康托展开--逆运算

例 {1,2,3,4,5}的全排列,并且已经从小到大排序完毕

(1)找出第96个数

首先用96-1得到95

用95去除4! 得到3余23

有3个数比它小的数是4

所以第一位是4

用23去除3! 得到3余5

有3个数比它小的数是4但4已经在之前出现过了所以第二位是5(4在之前出现过,所以实际比5小的数是3个)

用5去除2!得到2余1

有2个数比它小的数是3,第三位是3

用1去除1!得到1余0

有1个数比它小的数是2,第二位是2

最后一个数只能是1

所以这个数是45321

(2)找出第16个数

首先用16-1得到15

用15去除4!得到0余15

用15去除3!得到2余3

用3去除2!得到1余1

用1去除1!得到1余0

有0个数比它小的数是1

有2个数比它小的数是3 但由于1已经在之前出现过了所以是4(因为1在之前出现过了所以实际比4小的数是2)

有1个数比它小的数是2 但由于1已经在之前出现过了所以是3(因为1在之前出现过了所以实际比3小的数是1)

有1个数比它小得数是2 但由于1,3,4已经在之前出现过了所以是5(因为1,3,4在之前出现过了所以实际比5小的数是1)

最后一个数只能是2

所以这个数是1435
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: