好熟悉的题目……但是忘了是怎么做的……好像是随机排列?
反正都是暴力,看了下网上的题解,好像也没有更好的正解了。有想法的告诉我一下蟹蟹~
题意
我们可以用1~n这n个数字用类似杨辉三角的方法加起来,我们就可以把他们拆回去。这样的排列可能有多种,我们要它字典序最小的一种。
思路
n比较小,考虑排列所有可能一个个试……这里用一下新东西。
next_permutation,意义为下一个排列,引用于<algorithm>头文件。
用法:next_permutation(a,a+n)表示排列a到a+n的下一种排序方法。若要排列整数,建立数组a,next_permutation(a,a+n)表示按字典序排列其第a[0]到a[n-1]元素。这和sort的范围表示类似。
next_permutation的返回值为布尔类型,如果能够继续排列并排列了就返回true。如果没有后续排列返回false。我们可以利用这个特性进行判断。
代码
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<algorithm> 5 #include<queue> 6 #include<cmath> 7 using namespace std; 8 int n,sum,a[100],A[100]; 9 void read(int &x) 10 { 11 char c=getchar(); 12 while(c<'0' or c>'9')c=getchar(); 13 x=c-'0',c=getchar(); 14 while(c>='0' and c<='9') 15 x*=10,x+=c-'0',c=getchar(); 16 } 17 int main() 18 { 19 read(n);read(sum); 20 if(n==1){ 21 printf("1\n");return 0; 22 } 23 for(int i=0;i<n;i++)A[i]=i+1; 24 do{//由于我们不想让next_permutation第一次就排列,我必须改掉总是先用while的坏习惯(并不 25 for(int i=0;i<n;i++)a[i]=A[i]; 26 int cur=n; 27 bool ok=0; 28 while(cur>1){ 29 for(int i=0;i<cur-1;i++)a[i]=a[i]+a[i+1]; 30 if(cur==2 and a[0]==sum) 31 { 32 printf("%d",A[0]); 33 for(int i=1;i<n;i++)printf(" %d",A[i]); 34 printf("\n"); 35 return 0; 36 } 37 cur--; 38 } 39 }while(next_permutation(A,A+n)); 40 }