Codeforces Round #610

A题

本题只需按题目所给条件实现就可,分类讨论也很快,注意a有可能小于b

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<algorithm>
using namespace std;
typedef long long ll;
int main(){
    int t;
    cin>>t;
    while(t--){
    int a,b,c,r;
  cin>>a>>b>>c>>r;
  if(a>b)
  swap(a,b);
  if(a<=c&&c<=b){
      int s1=b-a;
      cout<<max(0,c-a-r)+max(b-c-r,0)<<endl;
  }
  else if(c<a){
      int s1=b-a;
      cout<<max(0,s1-max(c+r-a,0))<<endl;
  }
  else if(c>b){
      int s1=b-a;
     cout<<max(0,s1-max(b-c+r,0))<<endl;
  }
    }
  
} 
View Code

B题

这题题意我比赛的时候没有看清,真实题意是,他不限定使用offer的次数,也就是说,当n小于k时只能一个一个买,当n大于k时我们可以选择购买k个,也可以一个个买。这也可以设计dp状态为f[i],前i个所需要的最大花费。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=2e5+10;
int a[N];
int f[N];
int main(){
     int t;
     cin>>t;
     while(t--){
         int n,p,k;
         cin>>n>>p>>k;
         memset(f,0,sizeof f);
         int i;
         for(i=1;i<=n;i++){
             scanf("%d",&a[i]);
         }
        sort(a+1,a+n+1);
        int res=0;
        for(i=1;i<=n;i++){
            if(i>=k)
            f[i]=min(f[i-1],f[i-k])+a[i];
            else
            f[i]=f[i-1]+a[i];
            if(f[i]<=p)
            res=i;
        }
        cout<<res<<endl;
    }
}
View Code

C题

本题是一道贪心问题,重点是发现假设我们加入t+1的位置不是必须要完成的时间点,那么我们就不可能在t这个位置离去,因为这样肯定不如t+1的时候离开好,所以我们需要枚举每个时间节点-1,但是要加上T这个点

特别注意的是,题目中代码是tim>=0的时候要进行更新,而不是单单>0因为如果等于0代表刚刚好在这个时刻结束,也需要更新答案

具体注释看代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=2e5+10;
struct node {
    int t;
    int p;
}num[N];
bool cmp(node x,node y){
    return x.t<y.t;
}
int main(){
     int m;
     cin>>m;
     while(m--){
       int n,t,a,b;
       cin>>n>>t>>a>>b;
       int s1=0,s2=0;
       int i;
       for(i=1;i<=n;i++){
           cin>>num[i].p;
           if(!num[i].p)
           s1++;
           else
           s2++;
       }
       for(i=1;i<=n;i++){
               cin>>num[i].t;
       }
       sort(num+1,num+1+n,cmp);
       num[n+1].t=t+1;
       num[n+1].p=0;
       int ans=0;
       int st1=0;
       int st2=0;
       for(i=1;i<=n+1;i++){//枚举在ti-1处离开 
              if(st1>t)//现在所需要的时间已经大于总时间,不必更新 
              break;
              if(num[i-1].t!=num[i].t){//可能存在两个时间点是相等的 
                    int tim=num[i].t-1;
                    tim-=st1;//剩余还有多少时间可以用 
                    int res=st2;// 之前已经累计的个数 
                    if(tim>=0){//先做小的再做大的 
                       res+=min(s1,tim/a);
                 tim-=min(s1,tim/a)*a;
                 res+=min(s2,tim/b);
                 ans=max(ans,res);    
              }
            }
          if(!num[i].p){
            s1--;
            st1+=a;
          }
          else{
              s2--;
              st1+=b;
          }
          st2++;
       }
       cout<<ans<<endl; 
    }
}
View Code
原文地址:https://www.cnblogs.com/ctyakwf/p/12221549.html