编程训练

小牛牛是牛牛王国的将军,为了训练出精锐的部队,他会对新兵进行训练。部队进入了n个新兵,每个新兵有一个战斗力值和潜力值,当两个新兵进行决斗时,总是战斗力值高的获胜。获胜的新兵的战斗力值就会变成对手的潜力值 + 自己的战斗力值 - 对手的战斗力值。败者将会被淘汰。若两者战斗力值一样,则会同归于尽,双双被淘汰(除了考察的那个新兵之外,其他新兵之间不会发生战斗) 。小牛牛想知道通过互相决斗之后新兵中战斗力值+潜力值最高的一个可能达到多少,你能帮助小牛牛将军求出来吗?

链接:https://www.nowcoder.com/questionTerminal/79190c8e6202414bad33d6e287b61f3d
来源:牛客网

输入描述:
输入包括n+1行,第一行包括一个整数n(1 ≤ n ≤ 10^5);
接下来的n行,每行两个整数x和y(1 ≤ x,y ≤ 10^9)

输出描述:

输出一个整数,表示新兵中战斗力值+潜力值最高的一个能达到多少。

输入例子:

2
1 2
2 1

输出例子:

4

个人想法

用一个数组y装那些潜力值大于能力值的士兵,这些士兵是攻击后总价值上升的士兵(值得攻击且击败后);
选取了考察的士兵之后,无法换士兵只能选择他的对手。由y可知击败对手最终得到的最大数量是有限的。所有最大值完全取决于选取考察士兵的初始价值。
从初始价值最大的开始尝试,是否能全部击败数组y中的士兵。

#include<iostream>
#include <algorithm> 
#include<vector>
using namespace std;

struct soldier
{
    int attend;
    int potential;
    int value;
    bool operator < (const soldier &m)const {
        return value > m.value;
    }
};

bool SortByAttend(const soldier & m1, const soldier & m2) {
    return m1.attend < m2.attend;
}

int main() {
    int n, s, q;
    cin >> n;
    vector<soldier>x,y;
    for (int i = 0; i < n; i++) {
        soldier A = soldier();
        cin >> s >> q;
        A.attend = s;
        A.potential = q;
        if (s >= q)A.value = s + q;
        else {
            A.value = 2 * s;
            y.push_back(A);//只存放值得攻打的士兵
        }
        x.push_back(A);
    }
    sort(x.begin(), x.end());//建立最大堆,得到攻击力+潜力最大的那个
    //printf("最大的为 %d \n ", x[0].attend);
    sort(y.begin(), y.end(), SortByAttend);

    int max = 0,j = 0;
    soldier current;

    while (j<x.size()) {
        int i = 0;
        current = soldier();
        current.attend = x[j].attend;
        current.potential = x[j].potential;
        current.value = x[j].value;
        for (; i < y.size(); i++) {
            if (current.attend > y[i].attend) {
                current.attend = current.attend - y[i].attend + y[i].potential;
                current.value = current.value - y[i].attend + y[i].potential;
            }
            else break;
        }
        if (i == y.size()) {
            printf("%d", current.value < max ? max : current.value);
            break;
        }   
        else {
            max = max < current.value ? current.value : max;
            j++;
        }   
    }



    system("pause");
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值