[题目解析]培养魂灵

此篇较长,为了节省篇幅,提前说一下哈,不是满分代码就不展开详细讲述了。

↓仔细看题↓

培养魂灵 (pet)

时间限制: 1000 ms 空间限制: 262144 KB

题目描述

今天小Y准备选购一批魂灵。具体来说,这批魂灵共有N个,每一个魂灵都具有一个力量Pi。小Y特别喜欢 1 号魂灵,所以小 Y一定会购买1号魂灵。

在购买完小Y想要的魂灵之后,小Y每天会分配B点魂力给魂灵们,每一个魂灵得到的魂力则由它的力量值决定,假设所有购买的魂灵力量值总和为 Sum,那么i号魂灵得到的魂力则为(Pi/sum)*B。

举例而言,若小Y购买的3个魂灵力量值分别为2、3、5,小Y每天会分配5点魂力给它们,那么它们每天得到的魂力就分别是1点、1.5点、2.5点。

同时,由于小Y特别喜欢1号魂灵,所以小Y要求 1 号魂灵每天得到的魂力值不低于 A。

现在小Y想要知道他至少需要放弃多少只魂灵。

输入

第一行三个整数N、B、A,含义见题面描述。
第二行包含N个整数Pi,分别表示每个魂灵的力量值。

输出

一行一个整数,表示小Y至少需要放弃多少只魂灵。

样例输入1
4 10 3
2 2 2 2

样例输入2
4 80 20
3 2 1 4

样例输入3
5 10 10
1000 1 1 1 1

样例输出

样例输出1
1

样例输出2
0

样例输出3
4

数据范围限制
对于30%的数据,N≤5。对于 60%的数据,N≤20。
对于100%的数据,N≤1000。
提示
在样例1中,小Y至少需要放弃 2~4 中的某一个魂灵。
在样例2中,1号魂灵得到的魂力足够,小Y不需要放弃魂灵。
在样例3中,小Y需要放弃 2~5 中的所有魂灵。

这道题目一开始做的时候,我没有考虑周到,先看看零分代码吧↓

//0分
#include<bits/stdc++.h>
using namespace std;
long long n,b,a;
double k[1001],p[1001],s,mn=-9999999;
int main()
{
 cin>>n>>b>>a;
 for(int i=1;i<=n;i++){
  cin>>p[i];
  s+=p[i];
 }
 for(int i=1;i<=n;i++){
  k[i]=(p[i]/s)*b;
  if(k[i]<mn){
   mn=k[i];
  }
 }
 if(k[1]>=a){
  cout<<"0";
 }
 else{
  b-=k[1];
  b/=mn;
  cout<<b;
 }
}

这段代码是我用了较少的时间做出来的第一版本,当时头脑一热,就先求出每只魂灵得到的魂力值,然后求出最小值,再看看需不需要抛弃,如果要就抛弃最小值的那只魂灵。结果分数出来,当时我就傻了,怎么零分了呢?◔ ‸◔?

顿时我脑袋里又闪过一丝想法,于是就有了接下来的N个12.5分代码(这里仅展示第一个12.5分代码)↓

//12.5分
#include<bits/stdc++.h>
using namespace std;
long long n,b,a,s,p[1001],ans;
double k[1001];
int main()
{
 cin>>n>>b>>a;
 for(int i=1;i<=n;i++){
  cin>>p[i];
  s+=p[i];
 }
 for(int i=1;i<=n;i++){
  k[i]=(p[i]*1.0/s)*b;
 }
 if(k[1]>=a){
  cout<<0;
 }
 sort(k+2,k+n+1);
 for(int i=n;i>=2;i--){
  if(k[1]<a){
   ans++;
   a-=k[i];
  }
 }
 cout<<ans;
 return 0;
}

这份代码我稍加修饰,先把除了第一只魂灵以外的其他魂灵得到的魂力值排个序,然后再依次抛弃,直到不需要抛弃为止。这份代码我感觉好像对了,但是还是只拿了12.5分。

接下来看看我的25分代码吧,这个是我的升级版代码,嗯,但是成绩也不咋地。↓

//25
#include<bits/stdc++.h> 
using namespace std;
long long n,b,a,s,p[1001],ans;
double k[1001];
int main()
{
 cin>>n>>b>>a;
 for(int i=1;i<=n;i++){
  cin>>p[i];
  s+=p[i];
 }
 k[1]=(p[1]*1.0/s)*b;//求出第一只魂灵得到的魂力值 
 for(int i=2;i<=n;i++){
  k[i]=(p[i]*1.0/s)*b;//求出每一个魂灵得到的魂力值 
  if(k[i]>=(a-k[1])){//如果只抛弃一只就可以 
   cout<<1;//直接输出 
   return 0;
  }
  else if(k[i]<(a-k[1])){//如果不能只抛弃一只,那么就先抛弃当前魂灵 
   ans++;//累加器 
  }
  else{
   ans=n-1;//如果实在不行那么就除了第一只以外其他全部抛弃 
  }
 }
 if(k[1]>=a){//如果本身一只都不用抛弃 
  cout<<0;//输出零 
 }
 else{
  cout<<ans;//其余情况输出ans 
 }
}

你肯定已经发现了,这份代码漏洞极多,多到数不过来,天哪,太可怕了ヽ(*。>Д<)o゜(具体解析看注释)

不多说了,接下来,你猜我改对了吗?然鹅,并没有⊙﹏⊙‖∣,接下来我的37.5分代码出炉了↓

//37.5
#include<bits/stdc++.h>
using namespace std;
int temp1,ans,n,a,b,x,y,j,f[1001],temp2;
int main()
{
 x=1;
 cin>>n>>b>>a>>x;
 temp1+=x;
 for(int i=2;i<=n;i++){
  cin>>f[i];
  temp1+=f[i];
  if(f[i]>temp2)temp2=f[i];
 }
 if(x*1.0/temp1*b>=a){
  cout<<"0";
  return 0;
 }
 sort(f+2,f+n);
 y=n-1;
 while(x*1.0/temp1*b<a){
  temp1-=temp2;
  ans++;
  temp2=f[y];
  y--;
 }
 cout<<ans;
 return 0;
}

这份代码不多解释,就是25分代码的升级版而已,没想到就多了12.5分。(__) 嘻嘻

接下来,历时两天的AC代码终于闪亮✧(≖ ◡ ≖✿)登场了↓

#include<bits/stdc++.h>
using namespace std;
int sum,ans,n,a,b,x,y,j,f[1001],maxn;
int main()
{
 x=1;
 cin>>n>>b>>a>>x;
 sum+=x;
 for(int i=2;i<=n;i++){
  cin>>f[i];
  sum+=f[i];//求出魂灵力量值总和 
  if(f[i]>maxn)maxn=f[i];//求出最大力量值 
 }
 if(x*1.0/sum*b>=a){//如果一只都不用抛弃 
  cout<<"0";//输出零 
  return 0;
 }
 sort(f+2,f+n+1);//排个序 
 y=n-1;//目前魂灵数量 
 while(x*1.0/sum*b<a){
  sum-=maxn;//每次减去一个目前最大值 
  ans++;//累加器++ 
  maxn=f[y];//将目前最大值重新设置 
  y--;//目前魂灵数量减一 
 }
 cout<<ans;
 return 0;
}

(详见注释,不多解释)

至此,这道题已经折磨了我两天之久,终于完成了♪(^∀^●)ノ,如果你对于这篇文章有什么不懂或者这篇文章有什么缺点请在留言区留言,谢谢!!!!

(第一次写博客,多多指教)

posted @ 2022-03-25 20:11  zswangziye  阅读(26)  评论(0编辑  收藏  举报