Codeforces Round #645 Div.2
A. Park Lighting(签到)
题意:每盏路灯可以照亮两个格子,求照亮全部格子最少需要多少盏路灯。
题记:将所有格子的数量除以二向上取整即可。
#include<bits/stdc++.h>
using namespace std;
int main(){
int T;
cin>>T;
while(T--){
int n,m;
cin>>n>>m;
cout<<(n*m+1)/2<<endl;
}
return 0;
}
B. Maria Breaks the Self-isolation(阅读理解)
题意:有n个老奶奶,房间里本来就有一个老奶奶,当邀请第i个老奶奶来房间时房间里必须要有a[i]个老奶奶,老奶奶是同时一瞬间到达房间的,所以同一时间来的老奶奶也算上。
例如样例
6
1 5 4 5 1 9
可以同时邀请前五位老奶奶过来,那么每个老奶奶到达时看到房间里是有5个人的,所以答案是6(加上房间里本来有的老奶奶)。
题记:直接模拟即可。
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int a[N];
int main(){
int T;
cin>>T;
while(T--){
memset(a,0,sizeof(a));
int n;
cin>>n;
int x,mmax=0;
for(int i=1;i<=n;i++){
cin>>x;
a[x]++;
mmax=max(mmax,x);
}
int ans=0,sum=0;
for(int i=1;i<=mmax;i++){
sum+=a[i];
if(sum>=i)
ans=sum;
}
cout<<ans+1<<endl;
}
return 0;
}
C. Celex Update(找规律)
题意:给出题目图示的图形,求出从(x1,y1)到(x2,y2)有多少种路径值是不同的。
题记:找到规律即可。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){
int T;
cin>>T;
while(T--){
ll x1,y1,x2,y2;
cin>>x1>>y1>>x2>>y2;
cout<<(x2-x1)*(y2-y1)+1<<endl;
}
return 0;
}
D. The Best Vacation(二分)
题意:有n个月份,每个月份有a[i]天,在第a[i]天会得到a[i]的数值,找一个连续x天的区间,使得值最大。
题记:首先需要找到一个规律,要使值最大最后一天一定是在某一个月的最后一天(找多几个例子模拟一下)。
由于可以跨年份得找区间(即数组形成一个环),所以把数组开多一倍模拟第二年。然后求两个前缀和。第一个前缀和是前n个月一共有多少天,第二个前缀和是前n个月的值的总和。
最后遍历一下,当天数超过x时,找到第一个大于等于b[i]-x的月份的下标,即这个月之前的月份不要,这个月只取一部分天数,这个月之后的都取。将这个月之后的值加上这个月取的值即可。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+10;
ll a[N*2],b[N*2],c[N*2];
int main(){
ll n,x;
cin>>n>>x;
for(int i=1;i<=n;i++){
cin>>a[i];
a[n+i]=a[i];
}
n*=2;
for(int i=1;i<=n;i++){
b[i]=b[i-1]+a[i];//数组的前缀和
c[i]=c[i-1]+a[i]*(a[i]+1)/2;//值的前缀和
}
ll ans=0;
for(int i=1;i<=n;i++){
if(b[i]>=x){
int pos=lower_bound(b+1,b+1+n,b[i]-x)-b;
ll s=x-(b[i]-b[pos]);
ll sum=(c[i]-c[pos])+(a[pos]+a[pos]-s+1)*s/2;
ans=max(sum,ans);
}
}
cout<<ans<<endl;
return 0;
}