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