2011-12-27 12:28:09
地址:http://acm.hdu.edu.cn/showproblem.php?pid=1027
题意:求n个数的第m个排列。
mark:最简单快捷有效的方法当然是用next_permutation,但是为了锻炼代码能力还是自己写一下。
用flag标记已经选过不能选的数字,find用来查找最小的第num个数字。
因为m最多只有10000, 所以当n大于8的时候不需要考虑,直接输出最小的数,递归处理。
代码:
# include <stdio.h>
# include <string.h>
int flag[1010] ;
int label ;
int factorial[] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880} ;
int find(int num)
{
int i, cnt = 0 ;
for (i = 1 ; i <= 1000 ; i++)
{
if (flag[i] == 0) cnt++ ;
if (cnt == num)
{
flag[i] = 1 ;
return i ;
}
}
return -1 ;
}
void gao (int n, int m)
{
int idx ;
if (label == 0) label = 1 ;
else printf (" ") ;
if (n == 1)
{
printf ("%d", find(1)) ;
return ;
}
if (n > 8)
{
printf ("%d", find(1)) ;
gao (n-1, m) ;
return ;
}
printf ("%d", find((m-1)/factorial[n-1] + 1)) ;
gao(n-1, (m-1)%factorial[n-1]+1) ;
}
int main ()
{
int n, m ;
while (~scanf ("%d %d", &n, &m))
{
memset (flag, 0, sizeof (flag)) ;
label = 0 ;
gao (n, m) ;
puts ("") ;
}
return 0 ;
}