排列 POJ - 1833(输入输出优化 next_permutation()函数)
排列 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; }