Codeforces Round #622 (Div. 2)【A、B、C】(题解)(持续更新)

涵盖知识点:思维、构造、单调栈/线段树分治。

比赛链接:

http://codeforces.com/contest/1313

A:Fast Food Restaurant

题意:三个物品各有a,b,c个,问最多可以形成多少组合。

题解:排序后从多的开始减,七种情况枚举一遍即可。

Accept Code:

 1 #include <bits/stdc++.h>
 2 typedef long long ll;
 3 using namespace std;
 4 int main(){
 5     int t;
 6     scanf("%d", &t);
 7     while (t--){
 8         int a,b,c,res=0;
 9         cin>>a>>b>>c;
10         if(a)a--,res++;
11         if(b)b--,res++;
12         if(c)c--,res++;
13         if(a>b)swap(a,b);
14         if(a>c)swap(a,c);
15         if(b>c)swap(b,c);
16         if(b&&c)b--,c--,res++;
17         if(a&&c)a--,c--,res++;
18         if(a&&b)a--,b--,res++;
19         if(a&&b&&c)res++;
20         cout<<res<<"
";
21     }
22 }

B:Different Rules

题意:给第一场的排名x和第二场的排名y,问最多、最少几个人两场排名和小于等于你。

题解:

  1.最多就是构造尽可能多的人排名等于x+y,所以答案为x+y-1和n之间的最小值。

  2.最少分两种情况讨论:

    1)x+y<=n:可以构造其他所有人都大于等于n。所以答案为1.

    2)others:构造前t个人尽可能小。所以解不等式x-t+y-t<=n-t。解出t>=x+y-n。所以答案为x+y-n+1。

Accept Code:

 1 #include <bits/stdc++.h>
 2 typedef long long ll;
 3 using namespace std;
 4 int getmax(int n,int x,int y){
 5     return min(n,x+y-1);
 6 }
 7 int getmin(int n,int x,int y){
 8     if(x+y<=n)return 1;
 9     return min(n,x+y-n+1);
10 }
11 int main(){
12     int t;
13     cin>>t;
14     while (t--){
15         int n,x,y;
16         cin>>n>>x>>y;
17         cout<<getmin(n,x,y)<<" "<<getmax(n,x,y)<<"
";
18     }
19 }

C:Skyscrapers

题意:构造一个单峰序列,每个位置有最大值限制。使得最后总和最大。

题解:利用单调栈维护出前缀和以及后缀和。遍历所有点得出最大值所在的峰值下标。最后向两边重新给数组赋值即可。另有分治得出最小值并使用线段树维护区间的方法。

复杂度:除去单调栈O(n)。线段树最好O(nlogn)。

Accept Code:

 1 #include <bits/stdc++.h>
 2 typedef long long ll;
 3 using namespace std;
 4 const int maxn=5e5+10;
 5 ll a[maxn],pre[maxn],nxt[maxn],l[maxn],r[maxn];
 6 int main(){
 7     int n;
 8     cin>>n;
 9     a[0]=a[n+1]=0;
10     for(int i=1;i<=n;i++){
11         cin>>a[i];
12     }
13     stack<int> s;
14     s.push(0);
15     for(int i=1;i<=n;i++){
16         while(a[s.top()]>a[i])
17             s.pop();
18         pre[i]=s.top();
19         s.push(i);
20         l[i]=l[pre[i]]+a[i]*(i-pre[i]);
21     }
22     while(!s.empty())
23         s.pop();
24     s.push(n+1);
25     for(int i=n;i>=1;i--){
26         while(a[s.top()]>a[i])
27             s.pop();
28         nxt[i]=s.top();
29         s.push(i);
30         r[i]=r[nxt[i]]+a[i]*(nxt[i]-i);
31     }
32     int idx=0;
33     ll res=0;
34     for(int i=1;i<=n;i++){
35         if(res<l[i]+r[i]-a[i])
36             res=l[i]+r[i]-a[i],idx=i;
37     }
38     for(int i=idx-1;i>=1;i--){
39         a[i]=min(a[i],a[i+1]);
40     }
41     for(int i=idx+1;i<=n;i++){
42         a[i]=min(a[i],a[i-1]);
43     }
44     for(int i=1;i<=n;i++){
45         cout<<a[i]<<" ";
46     }
47     cout<<"
";
48 }

D:Happy New Year

E:Concatenation with intersection

原文地址:https://www.cnblogs.com/charles1999/p/12356565.html