POJ 1833 排列 next_permutation函数的运用,简单模拟题

中文题目。。

c++特有的一个函数  next_permutation  包含在 <algorithm> 头文件中,返回bool值,其规范表达为:

bool next_permutation (BidirectionalIterator first,
                         BidirectionalIterator last, Compare comp);

默认有三个参数,起始位置,终值位置,比较方式,前两个必须要有,第三个缺省的时候默认按照字典序,每次调用该函数,它将地址为[ first , last )的元素按照cmp的方式来寻找下一个全排列,并且遵循:

“If the function can determine the next higher permutation, it rearranges the elements as such and returns true. If that was not possible (because it is already at the largest possible permutation), it rearranges the elements according to the first permutation (sorted in ascending order) and returns false.”


(source:http://www.cplusplus.com/reference/algorithm/next_permutation/)

也就是说,如果能找到比当前排列更“大”的排列,就将该序列替换为这个更大的,并返回true,如果找不到更“大”的排列,换句话说,当前排列已经是最大的,就将序列替换为所有排列中最“小”的那个,并返回false

这个题正是用到了这个特性

剩下的问题就是模拟了

最开始写这个题的时候不知道这个函数处理到最大的排列的时候是怎么继续进行的,我还以为是返回false然后什么都不做,所以还手写了一个判定机制,代码长度立刻就上去了。。也贴出来吧,虽然里面多此一举了。

另外就是,无论有没有多此一举,代码用 G++交永远都是TLE,用C++交就没问题。对于编译器的差别我实在是无语,估计是因为牵扯到了stl,不同编译器的处理不一样吧,这个问题以后再解决。。

多此一举的代码:

/*Code by : skyword 
  Memory  : 136 kb
  Time    : 454 ms
  Length  : 1712 bytes
  Result  : Accepted
*/
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<cstring>
#include<vector>
#include<string>
#include<cmath>
#include<stack>
//#define file
#define maxn 100010
using namespace std;
int t;
int n,k;
int seq[1050];
bool cmp(int a,int b)
{
    return a<b;
}
int main()
{
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d %d",&n,&k);
        for(int i=0; i<n; i++)
        {
            scanf("%d",&seq[i]);
        }
        int i=0;
        bool flag;
        while(1)
        {
            flag=next_permutation(seq,seq+n,cmp);
            if(flag)
            {
                i++;
                if(i==k)
                {
                    for(int j=0; j<n; j++)
                    {
                        if(j<n-1)
                        {
                            printf("%d ",seq[j]);
                        }
                        else
                        {
                            printf("%d\n",seq[j]);
                        }
                    }
                    break;
                }
            }
            else
            {
                i++;
                for(int j=0; j<n; j++)
                {
                    seq[j]=j+1;
                }
                if(i==k)
                {
                    for(int j=0; j<n; j++)
                    {
                        if(j<n-1)
                        {
                            printf("%d ",seq[j]);
                        }
                        else
                        {
                            printf("%d\n",seq[j]);
                        }
                    }
                    break;
                }
            }
        }
    }
}

没有多此一举的代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

bool cmp(int a,int b)
{
    return a<b;
}

int main()
{

    int m,n,k,a[1100],i;

    scanf("%d",&m);
    while(m--)
    {
         memset(a,1100,sizeof(a));
        scanf("%d%d",&n,&k);
        for(i=0;i<n;i++)
        {
            scanf("%d",&a[i]);
        }
        //sort(a,a+n,cmp);

        while(k--)
        {
            next_permutation(a,a+n,cmp);
        }
        for(i=0;i<n;i++)
            printf("%d ",a[i]);
            printf("\n");
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值