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