hdu6789 Fight(2020百度之星初赛三/思维题/分类讨论)

题目

T(T<=100)组样例,每次给出三人初始攻击力x,y,z(1<=x,y,z<=1e3),

三人初始血量为1000,

对于每一轮,假设仍然剩下至少两个人的血量大于0,

那么选出两个血量大于0的人对打,他们的血量分别扣除和他们对打的另一个人的攻击力。

当有至少两个人的血量小于等于0时,游戏结束。

请问在最优情况下,这个游戏最少多少轮结束?

思路来源

https://blog.csdn.net/weixin_44412226/article/details/107604797

题解

排序使得x<=y<=z,暴力枚举x和y打了多少场,x和z打了多少场,

因为x攻击力低,不可能是最后的幸存者,

y和z如果均血量为正,就打到一方血量为负,

O(Tn²)枚举出最后的可能,思维比较明了一点

也可全排列6种情况O(n)枚举哪两个人先打多少轮,再让第三个人消灭掉第一个人,再消灭掉第二个人

代码

#include
using namespace std;
typedef long long ll;
int t,a[3],ans,cnt;
int main(){
    scanf("%d",&t);
    while(t--){
        ans=3000;
        for(int i=0;i<3;++i){
            scanf("%d",&a[i]);
        }
        sort(a,a+3);
        for(int i=0;i<=1000;++i){
            for(int j=0;j<=1000;++j){//02打
                int na=1000-i*a[1]-j*a[2];
                int nb=1000-i*a[0];
                int nc=1000-j*a[0];
                int tmp=i+j;
                //0如果可以把1、2打败 肯定不如其中一个败之后12互殴轮数少 故不用讨论
                if(nc>0 && nb>0){//12打
                    int cnt=min((nc+a[1]-1)/a[1],(nb+a[2]-1)/a[2]);
                    tmp+=cnt;
                    nc-=cnt*a[1];
                    nb-=cnt*a[2];
                }
                //printf("i:%d J:%d tmp:%d\n",i,j,tmp);
                if((nb<=0 && nc<=0) || (nb<=0 && na<=0) || (na<=0 && nc<=0)){
                    ans=min(ans,tmp);
                }
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}

 

你可能感兴趣的:(思维题)