poj 1146 && poj 1833

这两题基本类型很相似,所以把他们放到一起了。都是排列的一个问题,用stl里面提供的next_permutation这个函数就可以比较轻松的搞定。关键是想掌握next_permutation里面的基本算法,没什么难度,直接模拟可以水过。

/*poj 1146, Wrote by Dream Chen 2010/12/7*/

#include <iostream>
#include <algorithm>
using namespace std;
char data[60];
int main( ) 
{
	memset((void*)data,0,sizeof(data));
	while(cin >> data)
	{
		if (!strcmp(data,"#"))
		{
			break;
		}
		if (next_permutation(data,data+strlen(data)))
		{
			cout << data << endl;
		}
		else
		{
			cout << "No Successor" << endl;
		}
	}
	return 0;
}


/*poj 1833, Wrote by Dream Chen 2010/12/7*/

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

void OutPrint(int m);
int data[1100];
int n = 0;
int main( ) 
{
	scanf("%d",&n);
	for (int i = 0; i < n; ++i)
	{
		int m = 0;
		int k = 0;
		scanf("%d%d",&m,&k);
		//input the data
		memset((void*)data,0,sizeof(data));
		int j = 0;
		for (j = 0; j < m; ++j)
		{
			scanf("%d",&data[j]);
		}
		
		for (int t = 0; t < k; ++t)
		{
			next_permutation(data,data+m);
		}
		OutPrint(m);
		printf("/n");
	}
	return 0;
}

void OutPrint(int m)
{
	for (int i = 0; i < m; ++i)
	{
		printf("%d ",data[i]);
	}
}

另外,贴上next_permutation的一个非模块实现算法,是从网上一位童鞋那里copy的。

    
    
bool next_permutation(int a[], int len)
{
    if(len <=1||NULL==a)
        return false;
    int last = len - 1;
    int next = last;
    int next1;
    for(;;)
    {
        next1 = next;
        if(a[--next] < a[next1])//找到第一个比自己后面的元素小的元素,赋给next;
        {
            int mid = last+1;
            while(a[next]>=a[--mid]);//找到右边序列(注意右边序列为降序排列)中最右边的大于自己的元素,将其位置赋给mid。
            //交换a[mid]和a[next];右边得到一个新的降序排列的序列。
                int temp = a[mid];
            a[mid]=a[next];
            a[next]=temp;
            reverse<int*>(&a[next1],&a[last+1]);//反转右边的序列,使其升序排列。reverse为stl实现的反转算法。需要#include <algorithm>
            return true;
        }
        if(next==0)
        {
            reverse<int*>(&a[0],&a[last+1]);
            return false;
        }
    }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值