Poj 1833 排列 —— 一道水题的凌乱

  对于STL,许多ACMer都比较熟悉,那么今天,这里就有这么一道水题,体现出了关于STL的优美与不足,同时,也发现了一个问题,并且从中可以看出一些细节上的疏漏,可能导致各种各样问题。废话不多说,直接切入正题:

  

排列
Time Limit: 1000MS   Memory Limit: 30000K
Total Submissions: 11975   Accepted: 5064

Description

题目描述: 
大家知道,给出正整数n,则1到n这n个数可以构成n!种排列,把这些排列按照从小到大的顺序(字典顺序)列出,如n=3时,列出1 2 3,1 3 2,2 1 3,2 3 1,3 1 2,3 2 1六个排列。 

任务描述: 
给出某个排列,求出这个排列的下k个排列,如果遇到最后一个排列,则下1排列为第1个排列,即排列1 2 3…n。 
比如:n = 3,k=2 给出排列2 3 1,则它的下1个排列为3 1 2,下2个排列为3 2 1,因此答案为3 2 1。 

Input

第一行是一个正整数m,表示测试数据的个数,下面是m组测试数据,每组测试数据第一行是2个正整数n( 1 <= n < 1024 )和k(1<=k<=64),第二行有n个正整数,是1,2 … n的一个排列。

Output

对于每组输入数据,输出一行,n个数,中间用空格隔开,表示输入排列的下k个排列。

Sample Input

3
3 1
2 3 1
3 1
3 2 1
10 2	
1 2 3 4 5 6 7 8 9 10

Sample Output

3 1 2
1 2 3
1 2 3 4 5 6 7 9 8 10

Source

  此题甚是水,水道想都不想就敲上代码,用STL的next_permutation产生相应序列即可,然而,并没有想象之中的顺利,不断的超时让我不得其解,虽然知道STL的效率不是多么让人恭维,可不至于这样就杯具了,百度一下,果然大多用STL做的,这就让我有些摸不到头脑了,超时代码如下:

#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;

int num[1025];

int main()
{
    int n,k,m;

    scanf("%d",&m);

    while(m--)
    {
        scanf("%d%d",&n,&k);
        for(int i = 0; i < n; i ++)
        {
            scanf("%d",&num[i]);
        }
        for(int i = 0; i < k; i ++)
        {
            if(! next_permutation(num,num+n))
                sort(num,num+n,cmp);
        }

        printf("%d",num[0]);

        for(int i = 1; i < n; i ++ )
            printf(" %d",num[i]);
        putchar(10);

    }

    return 0;
}

后无奈,值得看别人代码,仔细推敲,发现症结所在,AC代码如下:

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <iterator>
 4 #include <stdio.h>
 5 
 6 using namespace std;
 7 
 8 int num[1024];
 9 
10 int main() //408K 516MS
11 {
12     int cas,n,k,i;
13     scanf("%d",&cas);
14     while(cas--)
15     {
16         scanf("%d%d",&n,&k);
17         for(i=0; i<n; i++)
18             scanf("%d",&num[i]);
19         for(i=0; i<k; i++)
20             next_permutation(num,num+n);
21 
22         copy(num,num+n-1,ostream_iterator<int>(cout," "));
23         cout<<num[n-1]<<endl;
24     }
25     return 0;
26 }
  

  此时,我们在这里又用了copy函数,也是属于STL的,这样就把重复调用printf的时间损失填补掉,实际上,当这么采用输出时,用时500ms左右,足以见得,用于输出(printf)的时间
至少耗用了500ms,感觉很不可思议。不过,这里用STL的copy函数提高效率的方式,很值得思考和学习的,当面临大量数据时,输入输出的消耗在所难免,甚至有时候会造成超时等问题,虽然9
printf的效率较高但多次调用势必会有所影响,而用copy将数据通过cout的迭代器进行输出,不失为一种值得考虑的方法。

posted @ 2012-04-17 22:12  寒风剑海  阅读(1690)  评论(0编辑  收藏  举报