CF_487A Fight the Monster(二分)

A. Fight the Monster
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

A monster is attacking the Cyberland!

Master Yang, a braver, is going to beat the monster. Yang and the monster each have 3 attributes: hitpoints (HP), offensive power (ATK) and defensive power (DEF).

During the battle, every second the monster's HP decrease by max(0, ATKY - DEFM), while Yang's HP decreases bymax(0, ATKM - DEFY), where index Y denotes Master Yang and index M denotes monster. Both decreases happen simultaneously Once monster's HP ≤ 0 and the same time Master Yang's HP > 0, Master Yang wins.

Master Yang can buy attributes from the magic shop of Cyberland: h bitcoins per HPa bitcoins per ATK, and d bitcoins per DEF.

Now Master Yang wants to know the minimum number of bitcoins he can spend in order to win.

Input

The first line contains three integers HPY, ATKY, DEFY, separated by a space, denoting the initial HPATK and DEF of Master Yang.

The second line contains three integers HPM, ATKM, DEFM, separated by a space, denoting the HPATK and DEF of the monster.

The third line contains three integers h, a, d, separated by a space, denoting the price of HPATK and DEF.

All numbers in input are integer and lie between 1 and 100 inclusively.

Output

The only output line should contain an integer, denoting the minimum bitcoins Master Yang should spend in order to win.

Sample test(s)
input
1 2 1
1 100 1
1 100 100
output
99
input
100 100 100
1 1 1
1 1 1
output
0
Note

For the first sample, prices for ATK and DEF are extremely high. Master Yang can buy 99 HP, then he can beat the monster with 1 HP left.

For the second sample, Master Yang is strong enough to beat the monster, so he doesn't need to buy anything.

题意:

奥特曼打小怪兽,各有血值,攻击力,防御力三个属性。每秒钟两个人同时掉血,分别为各自攻击力减去对方防御力。小怪兽攻击力比较强,但是奥特曼会开挂啊。去商店买属性,三个价钱还不一样,问怎样买能赢而且花钱最少。但是这道题要注意两个人是一起掉血,只要小怪兽被打死了,奥特曼剩一滴血也没事,但不能也挂了。

题解:

先找切入点,如果从加的属性来看的话三个属性,价钱不同,而且最优方案还是和具体情况相关,难度太大。换个切入点,我们可不可以二分找到最少的花钱数,从一个比较大的值开始不断二分,每次判断能不能打死,能打死继续分,打不死就是上一个。总能找到最小的花钱数。现在关键就是钱怎么花?价钱不一样,给谁感觉都不太合适,干脆就暴力一点,三个for循环,剪枝看能不能A得掉。设计成递减循环,有多少花多少一旦能干掉直接跳出,比从0开始慢慢加会快很多。

代码实现:

<span style="font-size:14px;">#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <cstring>
#define INF 0xffffff

using namespace std;

int y[3],m[3],p[3];//存的东西真多
int result;
bool solve(int);//解决函数
bool if_win(int,int,int);//传入三个属性加成,判断能不能成功打怪
int main()
{
    double lb=0,ub=INF;
    result=0xfffffff;
    scanf("%d%d%d",&y[0],&y[1],&y[2]);
    scanf("%d%d%d",&m[0],&m[1],&m[2]);
    scanf("%d%d%d",&p[0],&p[1],&p[2]);
    if(if_win(0,0,0))//先裸着打打看
    {
        printf("%d\n",0);
        return 0;
    }
    //二分找最少的钱数
    for(int i=0;i<100;i++)
    {
        int mid=(int)((lb+ub)/2+0.5);
        if(solve(mid)) ub=mid;
        else lb=mid;
        if(lb==ub||ub-lb==1) break;
    }
    printf("%d\n",result);
    return 0;
}
bool solve(int x)
{
    int i;//血值
    int j;//攻击力
    int z;//防御力
    for(i=x/p[0];i>=0;i--)
    {
        for(j=(x-i*p[0])/p[1];j>=0;j--)
        {
            //攻击力加了还没小怪兽防御力高就别打了,买装备去
            if(y[1]+j<m[2])
                break;
            for(z=(x-i*p[0]-j*p[1])/p[2];z>=0;z--)
            {
                int prise=p[0]*i+p[1]*j+p[2]*z;
                if(if_win(i,j,z))
                {
                    result=min(result,prise);
                    return true;
                }
            }
        }
    }
    return false;
}
bool if_win(int i,int j,int z)
{
    //这种肯定不行
    if(y[1]+j<=m[2])
        return false;
    //看看得打多少次
    int time=m[0]/(y[1]+j-m[2]);
    //要是不能刚好打死就再打一回合
    if(m[0]%(y[1]+j-m[2])!=0)
        time++;
    //看看奥特曼还有血吗?
    if(y[0]+i-time*(m[1]-y[2]-z)>0)
        return true;
    else
        return false;
}</span>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值