A题:https://codeforces.com/contest/1282/problem/A
题意:多组输入,在Ox坐标系中给你一个范围a-b,给你一个点,这个点有一个半径为r的覆盖范围,问:从a->b以每秒走1个单位长度的速度,其中在走完a,b时间内,其中有多少时间未在这个站点的覆盖范围内。
思路:这道题的话,a->b的总时间是max(a,b)-min(a,b)。仅需判断站点位于ab之间还是位于ab之外就行。
AC代码:
#include <bits/stdc++.h>
typedef long long ll;
const int maxx=10010;
const int inf=0x3f3f3f3f;
using namespace std;
int main()
{
int t;
cin>>t;
while(t--)
{
ll a,b,x,r;
cin>>a>>b>>x>>r;
ll min1=min(a,b);
ll max1=max(a,b);
a=min1;
b=max1;
ll w=x-r;
ll z=x+r;
ll ans;
if(z<=a||w>=b)
ans=0;
else
{
if(w<=a)
{
ans=min(b-a,z-a);
}
else if(z>=b)
{
ans=min(b-a,b-w);
}
else ans=z-w;
}
ans=b-a-ans;
cout<<ans<<endl;
}
return 0;
}
B题:https://codeforces.com/contest/1282/problem/B2
题意:在商店买东西,商店有n个物品,每个物品有自己的价格,商店有个优惠活动,当你买恰好k个东西时可以只为其中最贵的那个付款,求有限的钱中买到的最多的物品数量,你可以多次使用优惠。
思路:这道题的话,我们把所有商品的价格排序从小到大一遍,设第i个物品的价格是a[i],Sum[i]表示购买前i个物品花费的钱,作为前缀和。可以发现当你买了当第i个物品时,那么只需要支付Sum[i-k] + a [i] 即可,因为你买了当前的物品,可以赠送k-1个,那直接贪心着把小于等于当前这个物品价格的前K-1个物品直接赠送了,只需要支付a[i]费用,再支付一下sum[i-k]即可,维护整个过程sum[i] = sum[i-k] + a[i]即可。
AC代码:
#include <bits/stdc++.h>
typedef long long ll;
const int maxx=200010;
const int inf=0x3f3f3f3f;
using namespace std;
ll a[maxx];
int main()
{
int t;
cin>>t;
while(t--)
{
ll n,p,k;
cin>>n>>p>>k;
for(int i=1; i<=n; i++)
cin>>a[i];
sort(a+1,a+1+n);
ll ans=0;
ll sum[n+1];
memset(sum,0,sizeof(sum));
sum[0]=0;
sum[1]=a[1];
for(int i=2; i<=k; i++)
{
sum[i]=sum[i-1]+a[i];
}
for(int i=k; i<=n; i++)
{
sum[i]=sum[i-k]+a[i];
}
for(int i=0; i<=n; i++)
{
if(p>=sum[i])
ans=i;
}
cout<<ans<<endl;
}
return 0;
}
C题:https://codeforces.com/contest/1282/problem/C
题意: 有一个人参加考试,考试只有两种题,一种是简单题,每道题耗时固定为a;另一种是困难题,每道题耗时固定为b,保证b>a。解出一道题得分都是1。考试的规则并不只是写多少题得多少分,鼓励提前交卷。假如你没有提前交卷,那么有一部分的题目会列为“必做题”,当“必做题”的题目没有全部被完成的话,这门课就算0分;否则得到与题数相同的分数,包括“必做”和“非必做”的。
思路: 这道题的话,题意很明显,需要按题目的“必做时间”按照升序排列起来,然后贪心做,从头开始遍历每道题目的必做时间。假如遍历到第i个题了,当前时间为T,那么如果在T-1时刻交卷,首先需要把前面必须做的所有题目做完,假设这个过程花费了Ti时间,然后剩下了T - Ti的时间,那么我们就在剩下的时间内贪心着先做尽可能多剩余的简单题,再做难题,记录此时的ans,不断遍历所有题目的必须做时间到最后,也不断的更新ans的最大值。最终的ans就是答案。
AC代码:
#include <bits/stdc++.h>
typedef long long ll;
const int maxx=200010;
const int inf=0x3f3f3f3f;
using namespace std;
struct node
{
int x;
int y;
} edge[maxx];
bool cmp(node a,node b)
{
if(a.y!=b.y)
return a.y<b.y;
return a.x<b.x;
}
int main()
{
int tt;
cin>>tt;
while(tt--)
{
ll n,t,a,b;
cin>>n>>t>>a>>b;
ll cnt1=0,cnt2=0;
for(int i=1; i<=n; i++)
{
int num;
cin>>num;
if(num==0)
cnt1++;
else
cnt2++;
edge[i].x=num;
}
for(int i=1; i<=n; i++)
{
int T;
cin>>T;
edge[i].y=T;
}
sort(edge+1,edge+1+n,cmp);
edge[n+1].y=t+1;
ll ans=0,c1=0,c2=0;
for(int i=1; i<=n+1; i++)
{
ll tot=a*c1+b*c2;
ll time=edge[i].y-1-tot;
if(time>=0)
{
ll ta=min(time/a,cnt1-c1);
time-=ta*a;
ll tb=min(time/b,cnt2-c2);
ans=max(ans,c1+c2+ta+tb);
}
if(edge[i].x==0)
c1++;
else
c2++;
}
cout<<ans<<endl;
}
return 0;
}