这两题基本类型很相似,所以把他们放到一起了。都是排列的一个问题,用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;
}
}
}