小牛牛是牛牛王国的将军,为了训练出精锐的部队,他会对新兵进行训练。部队进入了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");
}