poj 1731 orders

来源:互联网 发布:cg绘画软件 编辑:程序博客网 时间:2024/05/01 03:04

题目大意:按字典序,求字符串的全排列

解题思路:组合数学的字典序法:

str[0....len-1];

从后往前扫描找到一个严格单调递增的连续子序列设为str[i....len-1],其中str[i] <= str[i-1];

在这个严格单调递增的子序列中,我们再从后往前找出第一个大于str[i-1]的字符,把这个字符和str[i]交换,然后在把str[i....len-1]进行反转。

例如3421

严格单调递增的后缀子序列为421

第一个比3大的数是4,交换344321,然后反转后面的后缀子序列,得4123则为3421的下一个序列。

#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>using namespace std;const int maxn = 210;char str[maxn];void reverse(char *pBegin, char *pEnd);int main(){while(scanf("%s", str) != EOF){int len = strlen(str), i;sort(str, str + len);bool flag = false;do{flag = false;printf("%s\n", str);for(i = len - 1; i > 0; i--){if(str[i] > str[i - 1]){flag = true;break;}}if(flag){int j;for(j = len - 1; j >= i; j--){if(str[j] > str[i - 1]){char tmp = str[i - 1];str[i - 1] = str[j];str[j] = tmp;break;}}reverse(str + i, str + len - 1);}} while(flag);}return 0;}void reverse(char *pBegin, char *pEnd){while(pBegin < pEnd){char tmp = *pEnd;*pEnd = *pBegin;*pBegin = tmp;pBegin++;pEnd--;}}