POJ3187 Backward Digit Sums
POJ3187 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 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| #include<iostream> #include<cstring> #include<cstdio> #include<algorithm> #include<queue> #include<cmath> using namespace std; int n,sum,a[100],A[100]; void read(int &x) { char c=getchar(); while(c<'0' or c>'9')c=getchar(); x=c-'0',c=getchar(); while(c>='0' and c<='9') x*=10,x+=c-'0',c=getchar(); } int main() { read(n);read(sum); if(n==1){ printf("1\n");return 0; } for(int i=0;i<n;i++)A[i]=i+1; do{ for(int i=0;i<n;i++)a[i]=A[i]; int cur=n; bool ok=0; while(cur>1){ for(int i=0;i<cur-1;i++)a[i]=a[i]+a[i+1]; if(cur==2 and a[0]==sum) { printf("%d",A[0]); for(int i=1;i<n;i++)printf(" %d",A[i]); printf("\n"); return 0; } cur--; } }while(next_permutation(A,A+n)); }
|