Codeforces Round #622 (Div. 2)
A. Fast Food Restaurant
题意
有三种食物,每个客人每样最多拿一个,每个客人拿的组合不能相同,问最多能供应多少个客人
题解
每样最多拿一个,一共有7种取法: a , b , c , a b , a c , b c , a b c a,b,c,ab,ac,bc,abc a,b,c,ab,ac,bc,abc,用7个if判断一下就好了
代码
#include<iostream>
#include<cstdio>
using namespace std;
int main()
{ long _,x,y,z,i,ans;
for(scanf("%ld",&_);_;_--){
scanf("%ld%ld%ld",&x,&y,&z);
if(x<y)swap(x,y);
if(x<z)swap(x,z);
if(y<z)swap(y,z);
ans=0;
if(x>=1){x--;ans++;}
if(y>=1){y--;ans++;}
if(z>=1){z--;ans++;}
if(x>=1&&y>=1){x--;y--;ans++;}
if(z>=1&&y>=1){z--;y--;ans++;}
if(x>=1&&z>=1){x--;z--;ans++;}
if(x>=1&&y>=1&&z>=1){x--;y--;z--;ans++;}
printf("%ld\n",ans);
}
return 0;
}
B. Different Rules
题意
定义一种新的最终排名的方法,使用两场比赛的排名相加得到最终分数,再按照这个分数重新排名得到最终排名(两场比赛中没有并列排名),给出某人的两场比赛排名 x x x和 y y y,求可能的最大最小最终排名
题解
因为总人数
n
n
n的范围超级大
[
1
,
1
0
9
]
[1,10^9]
[1,109],所以必须是结论题。
首先是最小排名,分两种情况:
1)
x
+
y
⩽
n
+
1
x+y \leqslant n+1
x+y⩽n+1
最优情况如图所示,排名为1
2)
x
+
y
>
n
+
1
&
&
y
≠
n
x+y > n+1 \&\& y \not= n
x+y>n+1&&y=n
如图,绿色和红色的匹配方式不变,但是个数变了,这时前面,黄色便是能超过自己的人,
N
−
(
N
−
Y
−
1
)
−
(
N
−
X
−
1
)
−
2
=
X
+
Y
−
N
N-(N-Y-1)-(N-X-1)-2=X+Y-N
N−(N−Y−1)−(N−X−1)−2=X+Y−N,然后+1就是最小排名了
综上,最小排名就是 m a x ( 1 , x + y − n + 1 ) max(1,x+y-n+1) max(1,x+y−n+1)
接下来看最大排名,因为相等也算输,所以尽量构造相等的就好了
由图可知,理想状态下答案就是
m
i
n
(
n
,
x
+
y
−
1
)
min(n,x+y-1)
min(n,x+y−1)
代码
#include<iostream>
#include<cstdio>
#define max(a,b) (((a)>(b))?(a):(b))
#define min(a,b) (((a)<(b))?(a):(b))
using namespace std;
int main()
{ long _,n,x,y;
for(scanf("%ld",&_);_;_--){
scanf("%ld%ld%ld",&n,&x,&y);
printf("%ld %ld\n",max(1,min(n,x+y-n+1)),max(1,min(n,x+y-1)));
}
return 0;
}
C2. Skyscrapers (hard version)
题意
建设大楼,要求每栋楼有限高,而且不允许存在一栋楼两边都有比他更高的楼,要求建成的楼总高度最大
ps:C1跟C2题目一样的,就不放了
题解
(按照思维上的难度,这题比B简单,题目安排的锅。。)
因为任何一栋楼都要满足题目的限制,所以可以任找一栋楼来作为起点来找规律。
对于找到的楼,向一个方向拓展时,如果是向低处的,那么这个方向上所有楼都得满足不上升,反之亦然。
由此可知,我们只需要找到一个“最高点”,向左向右全部向低处拓展就好了。
至于这个最高点,可以用dp预处理两个数组
l
l
l和
r
r
r,分别是从左向右和从右向左一路不下降高度建楼得到的总高度,最后得到的
l
[
i
]
+
r
[
i
+
1
]
l[i]+r[i+1]
l[i]+r[i+1]的最大值所在点就是“最高点”了
代码
#include<iostream>
#include<cstdio>
#include<stack>
#define min(a,b) (((a)<(b))?(a):(b))
#define ll long long
#define def 500010
using namespace std;
stack<ll>sta;
ll a[def],l[def],r[def];
int main()
{ ll n,i,maxx,minn;
scanf("%lld",&n);
for(i=1;i<=n;i++)
scanf("%lld",&a[i]);
for(i=1;i<=n;i++){
while(!sta.empty()&&a[i]<a[sta.top()])
sta.pop();
if(sta.empty())
l[i]=i*a[i];
else
l[i]=(i-sta.top())*a[i]+l[sta.top()];
sta.push(i);
}
while(!sta.empty())sta.pop();
for(i=n;i>=1;i--){
while(!sta.empty()&&a[i]<a[sta.top()])
sta.pop();
if(sta.empty())
r[i]=(n-i+1)*a[i];
else
r[i]=(sta.top()-i)*a[i]+r[sta.top()];
sta.push(i);
}
maxx=1;
for(i=1;i<n;i++)
if(l[i]+r[i+1]>l[maxx]+r[maxx+1])
maxx=i;
minn=a[maxx];
for(i=maxx;i>=1;i--){
minn=min(minn,a[i]);
a[i]=minn;
}
minn=a[maxx+1];
for(i=maxx+1;i<=n;i++){
minn=min(minn,a[i]);
a[i]=minn;
}
for(i=1;i<=n;i++)
printf("%lld ",a[i]);
printf("\n");
return 0;
}