A.Level Statistics
思路:对于每对 pi 和 ci 需要满足条件:pi-1 <= pi , ci-1 <= ci , pi - pi-1 >= ci -ci-1
#include<bits/stdc++.h>
using namespace std;
int p[1001],c[1001];
int main(){
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int t,n,i,flag;
scanf("%d",&t);
while(t--){
flag=0;
scanf("%d",&n);
for(i=1;i<=n;i++){
scanf("%d %d",&p[i],&c[i]);
if(p[i]<p[i-1]||c[i]<c[i-1]||(p[i]-p[i-1]<c[i]-c[i-1]))
flag=1;
}
if(flag) printf("NO\n");
else printf("YES\n");
}
return 0;
}
B.Middle Class
思路:题目中所要求的是实现共同富裕的最大人数,而显然易得的是,要在不使富人变穷的基础上使穷人变富才能求出最优解,因此可以用富人多出来的那些钱来填补穷人与富有标准 x 的距离,而为使人数最多,应当从距离最小的穷人开始填补
#include<bits/stdc++.h>
using namespace std;
vector<int> v;
bool cmp(int a,int b){return a>b;}
int main(){
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int t,n,x,i,cnt,a;long long sum;
scanf("%d",&t);
while(t--){
v.clear();
sum=0;cnt=0;
scanf("%d %d",&n,&x);
for(i=0;i<n;i++){
scanf("%d",&a);
if(a>x) sum+=a-x; //计算富人拥有的钱与x的差值的总和
if(a<x) v.push_back(a); //记录每个穷人的钱数
}
sort(v.begin(),v.end(),cmp); //对穷人按拥有的钱从大到小排序,便于使富裕人数最优
for(i=0;i<v.size();i++){ //用富人多余的钱对穷人逐个进行补足,从而实现共同富裕
if(x-v[i]<=sum){
sum-=x-v[i];
cnt++;
}
else break;
}
printf("%d\n",n-v.size()+cnt);
}
return 0;
}
C.Circle of Monsters
思路:每个怪物死了都得炸,那么不如先让它们把自己后面怪物都炸一遍,那么剩余的血量就是我们击败他们所需要的子弹数的基础(也就是说不能再少了,再少就打不完了…),接下来我们需要找我们第一个打败的怪物,因为这个怪物没法通过被炸削减血量,所以没被炸时所耗额外子弹数最小的怪物就是我们要找的第一个被击败的怪物
#include<bits/stdc++.h>
using namespace std;
long long a[300001],b[300001],c[300001],cnt;
int main(){
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int t,n,i,mi;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
mi=0;cnt=0;
for(i=0;i<n;i++){
scanf("%lld %lld",&a[i],&b[i]);
}
for(i=0;i<n;i++){
c[i]=min(a[i],b[i?i-1:n-1]); //计算每个怪物假如没被自己前面的怪物炸时所要消耗的额外子弹数
cnt+=max(a[i]-b[i?i-1:n-1],(long long)0); //计算每个怪物假如被自己的前面的怪物炸过了之后所要的消耗的子弹数
if(c[mi]>c[i]) mi=i; //找到第一个被杀的怪物的位置
}
cnt+=c[mi];
printf("%lld\n",cnt);
}
return 0;
}