Codeforces Round #540 (Div. 3)

A、题目意思理解就过了

B、读了题目没有写,但是依稀感觉是前缀和,不过写残了。题解代码非常简洁。

维护前缀、后缀奇数和,维护前缀、后缀偶数和。

题解把遍历过的数都减去了,也就维护了后缀和。

前缀过一个加一个。

 1 #include<bits/stdc++.h>
 2 typedef long long ll;
 3 int a[200010];
 4 
 5 int main() {
 6     int n,Osum=0,Esum=0,Oper=0,Eper=0;
 7     scanf("%d",&n);
 8     for(int i=0;i<n;i++) {
 9         scanf("%d",&a[i]);
10         if(i&1) Esum+=a[i];
11         else Osum+=a[i];
12     }
13     int cnt=0;
14     for(int i=0;i<n;i++) {
15         if(i&1) Esum-=a[i];
16         else Osum-=a[i];
17         if(Oper+Esum==Eper+Osum) cnt++;
18         if(i&1) Eper+=a[i];
19         else Oper+=a[i];
20     }
21     printf("%d\n",cnt);
22     return 0;
23 }
View Code

C、一个恶心的模拟?不过官方题解貌似不恶心

把矩阵位置分析一遍。然后只遍历四分之一(左上角),然后根据坐标对应4,2,1

然后就先放4再放2最后放1。

不能放的条件是放的数大于1000。

 1 #include<cstdio>
 2 #include<vector>
 3 #include<map>
 4 using namespace std;
 5 int a[1010],g[30][30];
 6 
 7 int main() {
 8     int n;
 9     scanf("%d",&n);
10     for(int i=0;i<n*n;i++) {
11         int x;
12         scanf("%d",&x);
13         a[x]++;
14     }
15     vector<pair<int,pair<int,int> > > ceils;
16     for(int i=0;i<(n+1)/2;i++) {
17         for(int j=0;j<(n+1)/2;j++) {
18             if((i!=n-i-1)&&(j!=n-j-1)) ceils.push_back({4,{i,j}});
19             else if((i!=n-i-1)^(j!=n-j-1)) ceils.push_back({2,{i,j}});
20             else ceils.push_back({1,{i,j}});
21         }
22     }
23    // printf("%d**%d\n",ceils.size(),a[2]);
24     int num[3]={4,2,1};
25     for(int i=0;i<3;i++) {
26         int cnt=1;
27         for(int j=0;j<ceils.size();j++) {
28             pair<int,pair<int,int> > tmp=ceils[j];
29             int cur=tmp.first;
30             int ni=tmp.second.first;
31             int nj=tmp.second.second;
32             if(cur!=num[i]) continue;
33             while(cnt<1001&&a[cnt]<cur) cnt++;
34             if(cnt>1000) {
35                 puts("NO");
36                 return 0;
37             }
38             g[ni][nj]=g[ni][n-nj-1]=g[n-ni-1][nj]=g[n-ni-1][n-nj-1]=cnt;
39 
40             a[cnt]-=cur;
41         }
42     }
43     puts("YES");
44     for(int i=0;i<n;i++) {
45         for(int j=0;j<n;j++) printf("%d ",g[i][j]);
46         printf("\n");
47     }
48     return 0;
49 }
View Code

D1、能看出来逆序是最大的,但是没有想到枚举天数来做。

D2、数据范围变大,果断二分。但是十个二分九个错。

总结两个写法。(经常写第一个,但是第二个貌似更稳)

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=2e5;
 4 int n,m,a[maxn];
 5 bool cmp(int a,int b) {
 6     return a>b;
 7 }
 8 
 9 int solve(int x) {
10     int sum=0;
11     for(int j=0;j<n;j++) {
12         sum+=max(a[j]-j/x,0);
13         if(sum>=m) {
14             return 1;
15         }
16     }
17     return 0;
18 }
19 
20 int main() {
21     scanf("%d%d",&n,&m);
22     for(int i=0;i<n;i++) scanf("%d",&a[i]);
23     sort(a,a+n,cmp);
24     int l=1,r=n+1;
25     while(l<r) {
26         int mid=(l+r)/2;
27         if(solve(mid)) {
28             r=mid;
29         } else l=mid+1;
30     }
31     printf("%d\n",r<=n?r:-1);
32 }
View Code
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=2e5;
 4 int n,m,a[maxn];
 5 bool cmp(int a,int b) {
 6     return a>b;
 7 }
 8 
 9 int solve(int x) {
10     int sum=0;
11     for(int j=0;j<n;j++) {
12         sum+=max(a[j]-j/x,0);
13         if(sum>=m) {
14             return 1;
15         }
16     }
17     return 0;
18 }
19 
20 int main() {
21     scanf("%d%d",&n,&m);
22     for(int i=0;i<n;i++) scanf("%d",&a[i]);
23     sort(a,a+n,cmp);
24     int l=1,r=n,ans=-1;
25     while(l<=r) {
26         int mid=(l+r)/2;
27         if(solve(mid)) {
28             ans=mid;
29             r=mid-1;
30         } else l=mid+1;
31     }
32     printf("%d\n",ans);
33 }
View Code

猜你喜欢

转载自www.cnblogs.com/ACMerszl/p/10452968.html