排列 POJ - 1833
2018-03-14 14:03:12
题意:小花被给出了一个数字n与一个数字k 还有一个由数字1~n组成的一个排列 问按照字典序 这个序列下面的第k个序列是什么样子的
思路:CCF讲课老师说这个题是第二题的难度 尚尚看到之后认为说第二题有点夸张了 比第二题稍微难一点点 这个题如果知道一个叫做next_permutation()的函数会好写很多 但是直接写不加任何优化的话会超时 因为什么 我也不知道 n*k的复杂度 不知道为什么会搞成这样 最后加了输入输出优化 就好了
另外还手写了一遍next_permutation()函数 思想就是 从后往前找 找到第一个a[i]>a[i-1]的数字 那么把第i-1位之后的 最小的且比a[i-1]大的数字与a[i-1]交换位置 然后将i-1位之后的数字排序
刚开始一直不过 因为忽略了要大于a[i-1]这个条件 例如 5 9 3 6 如果单纯只找最小的 那么下一个序列就会变为3 5 6 9 这个序列明显是在他前面的 错因在此
附直接调用函数代码一份 内含自己写的函数
#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define inf 1e9
int t , n , k;
int num[1030];
void read(int &x){
x=0;char c=getchar();
while(c<'0' || c>'9')c=getchar();
while(c>='0' && c<='9'){
x=x*10+c-'0';
c=getchar();
}
}
void write(int x){
if(x==0){putchar(48);return;}
int len=0,dg[20];
while(x>0){dg[++len]=x%10;x/=10;}
for(int i=len;i>=1;i--)putchar(dg[i]+48);
}
void input()
{
for(int i=0; i<n; i++)
read(num[i]);
}
void output()
{
for(int i=0; i<n-1; i++)
{
write(num[i]);
putchar(' ');
}
write(num[n-1]);
printf("\n");
}
//bool next_permutation_(int a[] , int b)///手写的next_permutation()函数 传入的不是num , num+n 而是num , n 这个时间上 不如直接调用
//{
////找到最小的比他的 比他大的
// int minn = inf;
// int whe;
// for(int i=b; i>0; i--)
// {
// if(a[i] > a[i-1])
// {
// sort(a+i , a+b);
// for(int j=i; j<b; j++)
// {
// if(a[j]>a[i-1])
// {
// whe = j;
// break;
// }
// }
// int tmp = a[i-1];
// a[i-1] = a[whe];
// a[whe] = tmp;
// sort(a+i , a+b);
// return true;
// }
// }
// return false;
//}
int main()
{
read(t);
while( t-- )
{
read(n);
read(k);
input();
for(int i=1; i<=k; i++)
{
if( !next_permutation(num , num+n))
{
sort(num , num+n);
}
}
output();
}
return 0;
}