题意: 给出n,m求第m小序列, (1.2.3.4....n) ( 1<=n<=1000, 1<=m<=10000 )
解法: 根据m的数据大小, 至多改变后面8位, 也就是8!, 可以进行模拟, 确定需要改变后面k位,然后,先输出前n-k位数, 对第n-k+1到n位的数进行模拟.
code:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<queue>
#include<stack>
#define inf 0x3f3f3f3f3f
using namespace std;
const int maxn = 100;
int num[11];
int sum[11];
void init(){
int i=1;
sum[0]=1;
while(i<10){
sum[i] = sum[i-1]*i;
i++;
}
return ;
}
int mark[11];
int main(){
//freopen("in.txt", "r", stdin);
init();
int n,m ,i, j, k;
sum[0]=1;
while(~scanf("%d %d", &n, &m)){
for(i=1; i<=9; i++){
if(sum[i] >= m) break;
}
for(j=1; j<=n-i; j++){
if(j!=1) printf(" ");
printf("%d", j);
}
for(int t=0;t<i; t++){ //收集后i个数
mark[t] = j++;
}
int p, q;
if(i){
while(i>0){
k = m/sum[i-1];
if(m%sum[i-1]==0) m-=(k-1)*sum[i-1];
else m-=k*sum[i-1], k++;
for(q=1,p=0; p<10;){
if(mark[p]>0) q++;
if(q>k) break;
p++;
}
printf(" %d", mark[p]);
mark[p]=-1;
i--;
}
}
printf("\n");
}
return 0;
}