D的小L
时间限制:4000 ms | 内存限制:65535 KB
难度:2
-
描述
-
一天TC的匡匡找ACM的小L玩三国杀,但是这会小L忙着哩,不想和匡匡玩但又怕匡匡生气,这时小L给匡匡出了个题目想难倒匡匡(小L很D吧
),有一个数n(0<n<10),写出1到n的全排列,这时匡匡有点囧了
,,,聪明的你能帮匡匡解围吗?
-
输入
- 第一行输入一个数N(0<N<10),表示有N组测试数据。后面的N行输入多组输入数据,每组输入数据都是一个整数x(0<x<10) 输出
-
按特定顺序输出所有组合。
特定顺序:每一个组合中的值从小到大排列,组合之间按字典序排列。
样例输入
-
2 2 3
样例输出
-
12 21 123 132 213 231 312 321
next_permutation的函数声明:#include <algorithm>
bool next_permutation( iterator start, iterator end);
next_permutation函数的返回值是布尔类型,在STL中还有perv_permutation()函数
next_permutation()函数功能是输出所有比当前排列大的排列,顺序是从小到大。
而prev_permutation()函数功能是输出所有比当前排列小的排列,顺序是从大到小。
next_permutation函数的原理如下:
在当前序列中,从尾端向前寻找两个相邻元素,前一个记为*i,后一个记为*t,并且满足*i < *t。然后再从尾端
寻找另一个元素*j,如果满足*i < *j,即将第i个元素与第j个元素对调,并将第t个元素之后(包括t)的所有元
素颠倒排序,即求出下一个序列了。
函数源码:
template<class Iterator>
bool next_permutation(Iterator first,Iterator last)
{
if(first == last)
return false;
Iterator i = first;
++i;
if(i == last)
return false;
i = last;
--i;
while(1)
{
Iterator t = i;
--i;
if(*i < *t)
{
Iterator j = last;
while(!(*i < *--j));
iter_swap(i,j);
reverse(t,last);
return true;
}
if(i == first)
{
reverse(first,last);
return false;
}
}
}
题解:此题十分简单,先用do——while循环输出最小的排列,再使用next_permutation()函数以此找到大于上个排列
的最小排列输出。
具体代码如下:
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
int n,x,i;
cin>>n;
while(n--)
{
int a[]={1,2,3,4,5,6,7,8,9,};
cin>>x;
do
{
for(i=0;i<x;i++)
cout<<a[i];
cout<<endl;
}while(next_permutation(a,a+x));
}
return 0;
}
/*do-while与while循环的区别在于:它先执行循环中的语句,然后再判断表达式是否为真 ,
如果为真就继续循环;若为假,就终止循环。 因此,do-while循环至少要执行一次循环语句 */