时间限制1.00s 内存限制125.00MB 难易度:普及−
【题目描述】
又是一年秋季时,陶陶家的苹果树结了 n 个果子。陶陶又跑去摘苹果,这次他有一个 a 公分的椅子。当他手够不着时,他会站到椅子上再试试。
这次与 NOIp2005 普及组第一题不同的是:陶陶之前搬凳子,力气只剩下 s 了。当然,每次摘苹果时都要用一定的力气。陶陶想知道在 s<0 之前最多能摘到多少个苹果。
现在已知 n 个苹果到达地上的高度 xi,椅子的高度 a,陶陶手伸直的最大长度 b,陶陶所剩的力气 s,陶陶摘一个苹果需要的力气 yi,求陶陶最多能摘到多少个苹果。
【输入格式】
第 1 行:两个数 苹果数 n,力气 s。
第 2 行:两个数 椅子的高度 a,陶陶手伸直的最大长度 b。
第 3 行~第 3+n−1 行:每行两个数 苹果高度 xi,摘这个苹果需要的力气 yi。
【输出格式】
只有一个整数,表示陶陶最多能摘到的苹果数。
【输入输出样例】
输入 #1
8 15 20 130 120 3 150 2 110 7 180 1 50 8 200 0 140 3 120 2
输出 #1
4
【说明/提示】
对于 100% 的数据,n≤5000, a≤50, b≤200, s≤1000, xi≤280, yi≤100。
【算法分析】
对于这道题,我们要节省陶陶的体力,才能摘更多的苹果,所以可以用一个sort排序,从小到大对摘苹果所需的体力排序,再判断能否摘到即可。
对于如何排序才能将苹果高度与所需体力排在一块,我在比赛时灵(脑)光(子)一(一)现(抽),写了一个歪到奶奶家的歪解,我对他的处理是:用一个数组储存 所需力气+0.001*苹果高度的值 ,在排序中所需力气占主导,在判断高度时用小数部分即可,如下:
#include <bits/stdc++.h>
using namespace std;
int n,s,a,b;
int x[6666],y[6666];
int sum=0;
double z[6666];
int main()
{
scanf("%d%d",&n,&s);
scanf("%d%d",&a,&b);
for(int i=1;i<=n;i++)
{
scanf("%d%d",&x[i],&y[i]);
z[i]=y[i]+0.001*x[i];
}
sort(z+1,z+1+n);
for(int i=1;i<=n;i++)
if((s>=(int)z[i])&&a+b>=1000*(z[i]-(int)z[i]))
{
sum+=1;
s-=(int)z[i];
}
cout<<sum;
return 0;
}
得了80分,哪个有兴趣的大佬可以在评论区帮改,正解是结构体,贴在下边了。
【参考代码】
#include <bits/stdc++.h>
using namespace std;
int n,s,a,b,x,y,cnt1,cnt2,ans;
struct apple
{
int xi,yi;
}ap[50005];
int cmp(apple x,apple y)
{
return x.yi<y.yi;
}
int main()
{
cin>>n>>s>>a>>b;
for(int i=1;i<=n;i++)
{
cin>>x>>y;
if(x<=a+b)
{
cnt1++;
ap[cnt1].xi=x;
ap[cnt1].yi=y;
}
}
sort(ap+1,ap+cnt1+1,cmp);
cnt2=s;
ans=0;
for(int i=1;cnt2>=ap[i].yi&&i<=cnt1;i++)
{
ans++;
cnt2-=ap[i].yi;
}
cout<<ans;
return 0;
}