返回顶部

Codeforces Round #623 (Div. 2, based on VK Cup 2019-2020 - Elimination Round, Engine)【A、B、C、D】(题解)

涵盖知识点:贪心、并查集、模拟。

比赛链接:

http://codeforces.com/contest/1315

A:Dead Pixel

题意:窗口中有一个坏点,求不包含坏点的最大矩形窗口面积。

题解:遍历被坏点分割的四个矩形区域取最大值即可。

Accept Code:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 int main(){
 5     int t;
 6     cin>>t;
 7     while(t--){
 8         int a,b,x,y;
 9         cin>>a>>b>>x>>y;
10         int res=0;
11         res=max(res,a*(b-y-1));
12         res=max(res,b*(a-x-1));
13         res=max(res,a*y);
14         res=max(res,b*x);
15         cout<<res<<"\n";
16     }
17     return 0;
18 }

 

B:Homecoming

题意:一条n个路口的路,每个路口有AB两种类型,对于i~j区间中,若所有值都相同,即可花费a或b从i到达j+1.现在总共有p的钱,问最小从哪个点开始可以到达第n个路口。

题解:逆向模拟。注意处理边界。

Accept Code:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 int main(){
 5     int t;
 6     cin>>t;
 7     while(t--){
 8         int a,b,p;
 9         cin>>a>>b>>p;
10         string s;
11         cin>>s;
12         for(int i=s.length()-2;i>=0;i--){
13             if(s[i]=='B')p-=b;
14             else p-=a;
15             if(p<0){
16                 cout<<i+2<<"\n";
17                 break;
18             }
19             bool flag=true;
20             for(int j=i-1;j>=0;j--){
21                 if(s[j]!=s[i]){
22                     flag=false;
23                     i=j+1;
24                     break;
25                 }
26             }
27             if(flag||i==0){
28                 cout<<"1\n";
29                 break;
30             }
31         }
32     }
33     return 0;
34 }

 

C:Restoring Permutation

题意:给定一个序列b。求是否存在最小的1~2n的排列a满足bi=min(ai*2-1,ai*2)。

题解:选定ai*2为第一个大于bi的值。若不存在则不存在序列。可用set二分,也可以遍历。

Accept Code:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=110;
 4 int a[maxn],b[maxn];
 5 bool vis[maxn<<1];
 6 void solve(){
 7     memset(vis,false,sizeof vis);
 8     int n;
 9     cin>>n;
10     for(int i=1;i<=n;i++) {
11         cin >> b[i];
12         vis[b[i]]=true;
13     }
14     for(int i=1;i<=n;i++){
15         a[i*2-1]=b[i];
16         bool flag=false;
17         for(int j=b[i]+1;j<=n*2;j++){
18             if(vis[j])continue;
19             vis[j]=true;
20             a[i*2]=j;
21             flag=true;
22             break;
23         }
24         if(!flag){
25             cout<<"-1\n";
26             return;
27         }
28     }
29     for(int i=1;i<=2*n;i++){
30         cout<<a[i]<<" ";
31     }
32     cout<<"\n";
33 }
34 int main(){
35     int t;
36     cin>>t;
37     while(t--){
38         solve();
39     }
40     return 0;
41 }

 

D:Recommendations

题意:给定所有书籍的本数以及增加1本所需消费。求最小花费使得所有书籍数量不同。

题解:贪心。所有书籍按照所需消费从大到小排序。越靠前增加的次数越少。并查集维护当前num至少要增加到多少。

Accept Code:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=2e5+10;
 4 typedef long long ll;
 5 struct Node{
 6     ll num,t;
 7     bool operator <(const Node &b)const{
 8         if(t==b.t)return num<b.num;
 9         return t>b.t;
10     }
11 }a[maxn];
12 map<int,int> pre;
13 int findx(int x){
14     return pre[x]==0?x:pre[x]=findx(pre[x]);
15 }
16 void merge(int x,int y){
17     int i=findx(x),j=findx(y);
18     if(i!=j)pre[i]=j;
19 }
20 int main(){
21     int n;
22     cin>>n;
23     for(int i=1;i<=n;i++)
24         cin>>a[i].num;
25     for(int i=1;i<=n;i++)
26         cin>>a[i].t;
27     sort(a+1,a+n+1);
28     ll ans=0;
29     for(int i=1;i<=n;i++){
30         int res=findx(a[i].num);
31         if(res==a[i].num)merge(res,res+1);
32         else{
33             merge(res,res+1);
34             ans+=1ll*(res-a[i].num)*a[i].t;
35         }
36     }
37     cout<<ans<<"\n";
38     return 0;
39 }

 

E:Double Elimination

F:Au Pont Rouge

posted @ 2020-02-24 20:49  Charles1999  阅读(252)  评论(0编辑  收藏  举报