yzoj P2345 战争 题解

纯数论

30分:纯暴力,直接模拟判断t秒后,判断hp是否小于0

60分: atk>=h,就是一炮一个,那么军队会在min(n,t)秒之后停止攻击,那么总伤害就是a[n+(n-1)
+(n-2)+........(n-min(n,t)+1)

等差数列求和d=a(2n-min(n,t)+1)*(min(n,t))/2;

如果d>=hp Yes,否则No;

100分

考虑前t秒军队伤害总和,然后和hp比较大小
先算几下打死一个士兵,设m下
那么前m秒伤害为nma
m+1到2m秒伤害为m(n-1)a
以此类推
如果没有支援,那么可以到m(1)a
那么我们考虑支援,将其分开算
对于前面的时间段,每个时间段经历m秒,设k表示有几个经历了m秒的时间段,那么

k=min(n,t/m)

设k个时间段的伤害为d=ma(n)+ma(n-1)......ma(n-k+1)
等差数列求和d=(ma(2n-k+1)k)/2

如果(t/m)<n && t mod m !=0则还有一个时间段,经历了t mod m秒
伤害为(t mod m)(a)(n-k)加入中

最后判断d>=hp如果是输出Yes,否则输出No

代码

#include<bits/stdc++.h>
using namespace std;
int T,flag;
long long hp,atk,n,h,a,t,atck,tmp,k;
int main(){
    scanf("%d",&T);
    while(T){
        scanf("%lld %lld %lld %lld %lld %lld",&hp,&atk,&n,&h,&a,&t);
        tmp=h/atk;
        if(h%atk!=0)tmp+=1;
        k=min(n,t/tmp);
        atck=tmp*a*(2*n-k+1)*k/2;
        if(t/tmp<n&&t%tmp!=0){
            atck+=t%tmp*a*(n-k);
        }
        if(atck>=hp){
            printf("Yes\n");
        }
        else printf("No\n");
        T--;
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/donkey2603089141/p/11416492.html