Sorry, your browser cannot access this site
This page requires browser support (enable) JavaScript
Learn more >

POJ3187 Backward Digit Sums

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

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

题意

我们可以用1~n这n个数字用类似杨辉三角的方法加起来,我们就可以把他们拆回去。这样的排列可能有多种,我们要它字典序最小的一种。

思路

\(n\) 比较小,考虑排列所有可能一个个试……这里用一下新东西。

next_permutation,意义为下一个排列,引用于 <algorithm> 头文件。

用法:next_permutation(a,a+n) 表示排列 aa+n 的下一种排序方法。若要排列整数,建立数组 anext_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));
}

给小狼留言