POJ3187 Backward Digit Sums

Backward Digit Sums

好熟悉的题目……但是忘了是怎么做的……好像是随机排列?

反正都是暴力,看了下网上的题解,好像也没有更好的正解了。有想法的告诉我一下蟹蟹~

题意

我们可以用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 }
原文地址:https://www.cnblogs.com/BrotherHood/p/12917696.html