2011-0006
从 Trac 迁移的文章
这是从旧校内 Wiki 迁移的文章,可能存在一些样式问题,您可以向 memset0 反馈。
原文章内容如下:
这题比较长,但是看懂后就比较简单了。大意是有两种兵种,机枪兵和护士,机枪兵有个血量hp和输出d,护士有个能量点e和输血速率h,还有一堆敌人,每秒输出a点伤害。
首先我们枚举机枪兵数量,然后分类讨论:
1)假如护士总输血速率大于等于敌人每秒输出伤害,那么我们可以以每秒a点输血保护机枪兵(这种情况下效率最高,因为hp不能突破上限),然后直到护士没能量了,这样机枪兵就跟裸打一样,一个公式。
2)假如小于,那么稍微麻烦些,首先要算出能量用完时敌人能杀掉多少人,然后算出这部分人的输出伤害,剩下的人也是裸打,这样又是一个公式。假如能量还没用完就全部被干掉了,可能需要特殊处理一下。
当然还有全部都是机枪兵时的特殊处理,总的来说有些麻烦,但不是难题。
这题我的程序比较奇葩,欢迎鄙视>_<
{{{
#include<cstdio>
int n,i,countmed,countkill,maxmar;
double d,h,hp,e,a,savetime,savepower,killtime,killpower,maxpower,dmg,totdmg,diepeoplelivetime,diepeoplepower,remainpower,remainpeople,nextpeoplelivetime,
firstpeopledietime,firstpeopledmg,totlivetime;
int main(){
while(scanf("%d",&n)!=EOF){
scanf("%lf%lf",&d,&h);
scanf("%lf%lf",&hp,&e);
scanf("%lf",&a);
maxpower=-1;
savetime=0;
savepower=0;
killtime=0;
killpower=0;
dmg=0;
totdmg=0;
diepeoplelivetime=0;
diepeoplepower=0;
remainpower=0;
remainpeople=0;
nextpeoplelivetime=0;
firstpeopledietime=0;
firstpeopledmg=0;
totlivetime=0;
for(i=1;i<=n;i++){
//i Marine
countmed=n-i;
if(countmed*h>=a){
//Save it!!
savetime=e*countmed;
savetime=savetime/a;
savepower=savetime*i*d;
//if(i==54)printf("%.6lf\n",savepower);
//Kill it!!
killtime=hp*(1+i);
killtime=killtime/2;
killtime=killtime/a;
killpower=killtime*i*d;
//if(i==54)printf("%.6lf\n",killpower);
if(savepower+killpower>maxpower){
maxpower=savepower+killpower;
maxmar=i;
}
}else{
if (countmed!=0){
//TRY TO SAVE IT
dmg=a-countmed*h;
savetime=e/h;
totdmg=savetime*dmg;
//TRY TO KILL SOME PEOPLE
countkill=totdmg/hp;
if(countkill>i){
countkill=i;
}
diepeoplelivetime=hp/dmg;
diepeoplepower=(1+countkill)*countkill/2*diepeoplelivetime*d;
//if(i==1)printf("%.6lf\n",diepeoplepower);
//And One People Feel Jiong
remainpower=0;
if (i-countkill>0){
firstpeopledmg=totdmg-countkill*hp;
firstpeopledietime=firstpeopledmg/dmg+(hp-firstpeopledmg)/a;
nextpeoplelivetime=hp/a;
remainpeople=i-countkill;
totlivetime=(firstpeopledietime*2+(remainpeople-1)*nextpeoplelivetime)*(remainpeople)/2;
remainpower=totlivetime*d;
}
if(remainpower+diepeoplepower>maxpower){
maxpower=remainpower+diepeoplepower;
maxmar=i;
}
}else{
firstpeopledietime=hp/a;
totlivetime=(1+n)*n*firstpeopledietime/2;
remainpower=totlivetime*d;
if(remainpower>maxpower){
maxpower=remainpower;
maxmar=i;
}
}
}
}
//printf("%.6lf\n",maxpower);
printf("%d\n",maxmar);
}
return 0;
}
}}}
Finished by Dai@NeverLand
这题比较长,但是看懂后就比较简单了。大意是有两种兵种,机枪兵和护士,机枪兵有个血量hp和输出d,护士有个能量点e和输血速率h,还有一堆敌人,每秒输出a点伤害。
首先我们枚举机枪兵数量,然后分类讨论:
1)假如护士总输血速率大于等于敌人每秒输出伤害,那么我们可以以每秒a点输血保护机枪兵(这种情况下效率最高,因为hp不能突破上限),然后直到护士没能量了,这样机枪兵就跟裸打一样,一个公式。
2)假如小于,那么稍微麻烦些,首先要算出能量用完时敌人能杀掉多少人,然后算出这部分人的输出伤害,剩下的人也是裸打,这样又是一个公式。假如能量还没用完就全部被干掉了,可能需要特殊处理一下。
当然还有全部都是机枪兵时的特殊处理,总的来说有些麻烦,但不是难题。
这题我的程序比较奇葩,欢迎鄙视>_<
#include<cstdio>
int n,i,countmed,countkill,maxmar;
double d,h,hp,e,a,savetime,savepower,killtime,killpower,maxpower,dmg,totdmg,diepeoplelivetime,diepeoplepower,remainpower,remainpeople,nextpeoplelivetime,
firstpeopledietime,firstpeopledmg,totlivetime;
int main(){
while(scanf("%d",&n)!=EOF){
scanf("%lf%lf",&d,&h);
scanf("%lf%lf",&hp,&e);
scanf("%lf",&a);
maxpower=-1;
savetime=0;
savepower=0;
killtime=0;
killpower=0;
dmg=0;
totdmg=0;
diepeoplelivetime=0;
diepeoplepower=0;
remainpower=0;
remainpeople=0;
nextpeoplelivetime=0;
firstpeopledietime=0;
firstpeopledmg=0;
totlivetime=0;
for(i=1;i<=n;i++){
//i Marine
countmed=n-i;
if(countmed*h>=a){
//Save it!!
savetime=e*countmed;
savetime=savetime/a;
savepower=savetime*i*d;
//if(i==54)printf("%.6lf\n",savepower);
//Kill it!!
killtime=hp*(1+i);
killtime=killtime/2;
killtime=killtime/a;
killpower=killtime*i*d;
//if(i==54)printf("%.6lf\n",killpower);
if(savepower+killpower>maxpower){
maxpower=savepower+killpower;
maxmar=i;
}
}else{
if (countmed!=0){
//TRY TO SAVE IT
dmg=a-countmed*h;
savetime=e/h;
totdmg=savetime*dmg;
//TRY TO KILL SOME PEOPLE
countkill=totdmg/hp;
if(countkill>i){
countkill=i;
}
diepeoplelivetime=hp/dmg;
diepeoplepower=(1+countkill)*countkill/2*diepeoplelivetime*d;
//if(i==1)printf("%.6lf\n",diepeoplepower);
//And One People Feel Jiong
remainpower=0;
if (i-countkill>0){
firstpeopledmg=totdmg-countkill*hp;
firstpeopledietime=firstpeopledmg/dmg+(hp-firstpeopledmg)/a;
nextpeoplelivetime=hp/a;
remainpeople=i-countkill;
totlivetime=(firstpeopledietime*2+(remainpeople-1)*nextpeoplelivetime)*(remainpeople)/2;
remainpower=totlivetime*d;
}
if(remainpower+diepeoplepower>maxpower){
maxpower=remainpower+diepeoplepower;
maxmar=i;
}
}else{
firstpeopledietime=hp/a;
totlivetime=(1+n)*n*firstpeopledietime/2;
remainpower=totlivetime*d;
if(remainpower>maxpower){
maxpower=remainpower;
maxmar=i;
}
}
}
}
//printf("%.6lf\n",maxpower);
printf("%d\n",maxmar);
}
return 0;
}
Finished by Dai@NeverLand