[agc008d]kth-k

题意:

给你一个长度为N的整数序列X,构造一个整数序列a满足:

1.a的长度为$N^2$,且1~N中每个数字恰好出现N次;

2.数字i在a中第i次出现的位置为$X_i$;

如果不能构造输出“No”,否则先输出“Yes”然后在第二行输出构造的序列(本题有SPJ)。

$1\leq N\leq 500$

$1\leq X_i\leq N^2$且$X_i$互不相同

题解:

我太菜了只会$O(n^3)$。。。dalao们纷纷$O(n^2)$碾了过去不知道比我快到哪里去了。。。

分别向前向后扫一遍,记录当前每个数字还需要填多少个,贪心填然后判断即可。

代码:

 1 #include<algorithm>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<cstdio>
 5 #include<cmath>
 6 #include<queue>
 7 #define inf 2147483647
 8 #define eps 1e-9
 9 using namespace std;
10 typedef long long ll;
11 int n,N,cnt=0,s[501],num[501],tot[501],a[250001];
12 int main(){
13     scanf("%d",&n);
14     for(int i=1;i<=n;i++){
15         scanf("%d",&num[i]);
16         a[num[i]]=i;
17         tot[i]=i-1;
18     }
19     N=n*n;
20     for(int i=1;i<=N;i++){
21         if(a[i])s[++cnt]=a[i];
22     }
23     for(int i=1;i<=N;i++){
24         if(a[i])continue;
25         for(int j=1;j<=n;j++){
26             if(!tot[s[j]])continue;
27             a[i]=s[j];
28             tot[s[j]]--;
29             break;
30         }
31     }
32     for(int i=1;i<=n;i++){
33         tot[i]=n-i;
34     }
35     for(int i=N;i;i--){
36         if(a[i])continue;
37         for(int j=n;j;j--){
38             if(!tot[s[j]])continue;
39             a[i]=s[j];
40             tot[s[j]]--;
41             break;
42         }
43     }
44     for(int i=1;i<=n;i++){
45         int tmp=0;
46         for(int j=1;j<=N;j++){
47             if(a[j]==i)tmp++;
48             if(tmp==i){
49                 if(j!=num[i])return puts("No"),0;
50                 break;
51             }
52         }
53     }
54     puts("Yes");
55     for(int i=1;i<=N;i++)printf("%d ",a[i]);
56     return 0;
57 }

我会说我考试时去atc的submission看了一下全是熟悉的id吗

posted @ 2018-09-29 16:50  DCDCBigBig  阅读(286)  评论(0编辑  收藏  举报