题解
- 这题用的是比较暴力的方法
- 首先,我们知道该数字可以为额外的话,也就是其他的n个都可以匹配成需要那样、
- 那么就暴力枚举n+1个数,判断哪个可以为额外的数字
- 怎么匹配呢
- 其实有一种很简单的想法
- 就是从大到小排序,向后匹配(也就是往后的2~a[1]+1个都减1)
- 如果是可以匹配的数的话,这个方法一定是可以匹配的
- 那么我们考虑一下时间复杂度,每次一个数要O(n^2(n+n*log2n))
- 只能过6个点
- 那么快排的时间可以不可以更优呢?
- 考虑一下,减完之后的序列为0+有序的序列(2~a[1]+1)+有序的序列(a[1]+2~n)
- 有那种方法是可以直接在O(n)的时间下合并两个有序的序列呢?
- 显然归并排序
- 最后判断一波,输出,AC,perfect
代码
1 #include<cstdio>
2 #include<iostream>
3 #include<algorithm>
4 using namespace std;
5 bool cmp(int x,int y){ return x>y; }
6 int n,a[510],x[510],y[510],tot,total,ans[510];
7 int main()
8 {
9 scanf("%d",&n);
10 for (int i=1;i<=n+1;i++) scanf("%d",&a[i]);
11 for (int i=1;i<=n+1;i++)
12 {
13 tot=0;
14 for (int j=1;j<=n+1;j++)
15 if (i!=j)
16 x[++tot]=a[j];
17 sort(x+1,x+n+1,cmp);
18 while (x[1]>0)
19 {
20 for (int j=2;j<=x[1]+1;j++) x[j]--;
21 int l1=2,r1=x[1]+1,l2=x[1]+2,r2=n;
22 tot=0; x[1]=0;
23 while (l1<=r1&&l2<=r2)
24 {
25 if (x[l1]<=x[l2]) y[++tot]=x[l2],l2++;
26 else y[++tot]=x[l1],l1++;
27 }
28 while (l1<=r1) y[++tot]=x[l1],l1++;
29 while (l2<=r2) y[++tot]=x[l2],l2++;
30 for (int j=1;j<=n;j++) x[j]=y[j];
31 }
32 sort(x+1,x+n+1,cmp);
33 if (x[n]==0) ans[++total]=i;
34 }
35 printf("%d
",total);
36 for (int i=1;i<=total;i++) printf("%d
",ans[i]);
37 return 0;
38 }