输入包括n+1行,第一行包括一个整数n(1 ≤ n ≤ 10^5); 接下来的n行,每行两个整数x和y(1 ≤ x,y ≤ 10^9)
输出一个整数,表示新兵中战斗力值+潜力值最高的一个能达到多少。
2 1 2 2 1
4
已知获胜战斗力值会加上对手的潜力值-对手的战斗力值。
贪心思想,要培养一个战力和潜力和最大的兵王,就要尽可能多的增加其战力,即打赢所有潜力大于战力的新兵,记他们的潜力战力差的总和为add。
选兵王,有两种情况:
#include<iostream>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
int main(){
int n;
long long maxZhan = 0, add = 0, maxSum = 0, tZhan, tQian;
cin >> n;
for(int i = 0; i < n; i++){
cin >> tZhan >> tQian;
//潜力比战斗力大,记录潜力与战力差的总和和其中最高的战斗力
if(tZhan < tQian) maxZhan = max(maxZhan, tZhan), add += tQian - tZhan;
//否则,记录最大的潜力、战力和
else maxSum = max(maxSum, tZhan + tQian);
}
cout << add + max(2 * maxZhan, maxSum) << endl;
return 0;
}
【正确理解题意】①题中要求除了除了考察的那个新兵之外,其他新兵之间不会发生战斗②题中没有要求考察的新兵与所有剩下的新兵都决斗。
import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;
public class Main{
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
Entity[] a = new Entity[n];
for (int i = 0; i < n; i++) {
a[i] = new Entity(sc.nextInt(), sc.nextInt());
}
Arrays.sort(a, new Comparator<Entity>() {
@Override
public int compare(Entity o1, Entity o2) {
return o1.x-o2.x!=0 ? o1.x-o2.x : o1.y-o2.y;
}
});
int max = 0; //x+y的最大值
int index = 0; // 下标
int cha = 0; // 差值
for (int i = 0; i < n; i++) {
if (a[i].x + a[i].y >= max || a[i].x + a[i].y + cha >= max) {
max = a[i].x + a[i].y;
cha = a[i].y - a[i].x;
index = i;
}
}
long res = max;
for (int i = index-1; i >= 0 ; i--) {
if (a[i].y > a[i].x) {
res += a[i].y - a[i].x;
}
}
System.out.println(res);
}
static class Entity {
int x;
int y;
public Entity(int x, int y) {
this.x = x;
this.y = y;
}
}
}
#include <iostream>
using namespace std;
int main(int argc, const char * argv[]) {
int n;
cin >> n;
long a[n][2];
for (int i = 0; i < n; i++) {
cin >> a[i][0] >> a[i][1];
}
long maxZ = 0, maxZQ = 0, sum = 0;
for (int i = 0; i < n; i++) {
if (a[i][1] - a[i][0] > 0) {
if (maxZ < a[i][0]) {
maxZ = a[i][0];
}
sum += a[i][1] - a[i][0];
} else {
if (maxZQ < a[i][0] + a[i][1]) {
maxZQ = a[i][0] + a[i][1];
}
}
}
if (2 * maxZ > maxZQ) {
sum += 2 * maxZ;
} else {
sum += maxZQ;
}
cout << sum;
return 0;
}
import java.util.*;
public class 训练部队{
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
Entity[] a = new Entity[n];
for (int i = 0; i < n; i++) {
a[i] = new Entity(sc.nextInt(), sc.nextInt());
}
Arrays.sort(a, new Comparator<Entity>() {
@Override
public int compare(Entity o1, Entity o2) {
return o1.x-o2.x!=0 ? o1.x-o2.x : o1.y-o2.y;
}
});
int max = 0; //x+y的最大值
int index = 0; // 下标
int cha = 0; // 差值
for (int i = 0; i < n; i++) {
if (a[i].x + a[i].y >= max || a[i].x + a[i].y + cha >= max) {
max = a[i].x + a[i].y;
cha = a[i].y - a[i].x;
index = i;
}
}
long res = max;
for (int i = index-1; i >= 0 ; i--) {
if (a[index].x!=a[i].x&&a[i].y > a[i].x) {
res += a[i].y - a[i].x;
}
}
System.out.println(res);
}
static class Entity {
int x;
int y;
public Entity(int x, int y) {
this.x = x;
this.y = y;
}
}
}
测试用例忽略了一些限制条件,就是与选中的人相同的战斗力的人之间是不能进行决斗的,
所以得把条件a[index].x!=a[i].x加上,就满足题意的要求了!
import java.util.Scanner;
/*
参考大神的解题思路:https://www.nowcoder.com/questionTerminal/79190c8e6202414bad33d6e287b61f3d
*
* 这道题目关键是理解题目意思,通俗的来说就是,从部队中挑选出一名战士,通过和其他人的斗争,可能获取到的最大值;
* 显然不能直接暴力,该战士只能与x<y(x代表战斗力,y代表潜能值)的人PK才能获取到经验值;
* 题目要求最大的x+y的值,通过比较可以求出战斗之后的sum(x-y)增量,还需要添加自己的能力值。
*
* 比较巧妙的地方就是,
* 1.如果该战士x<y的话,能力值已经计算过了,因此sum=sum-(y-x)+x+y=sum+2*x;
* 2.如果x>=y的话,sum = sum+x+y;
* 可以避免直接找到需要被训练的战士,只需要遍历中间过程找到x+y和2*x的最大值添加即可
* */
public class XunLeiSoldier {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()) {
int n = scanner.nextInt();
long sum = 0;
// 寻找的最大比较值
long comparedVal = 0;
for (int i = 0; i < n; i++) {
long x = scanner.nextInt();
long y = scanner.nextInt();
if (x < y) {
// 添加增量
sum += y - x;
comparedVal = Math.max(comparedVal, x + x);
} else {
comparedVal = Math.max(comparedVal, x + y);
}
}
System.out.println(comparedVal + sum);
}
}
}
#include<iostream>
#include<vector>
using namespace std;
int main(){
int n;
cin >> n;
long long x, y;
long long sumdeta = 0,maxx = 0,maxxy = 0;
for (int i = 0; i < n; i++){
cin >> x >> y;
if (y - x > 0){
sumdeta += y - x;
maxx = maxx > x ? maxx : x;
}
else
maxxy = maxxy > (x + y) ? maxxy : (x + y);
}
if (sumdeta + maxxy > sumdeta + 2 * maxx)
cout << sumdeta + maxxy;
else
cout << sumdeta + 2 * maxx;
}
package org.xwt.spring;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Scanner;
public class Soldier {
private int capacity;
private int potential;
public int getCapacity() {
return capacity;
}
public void setCapacity(int capacity) {
this.capacity = capacity;
}
public int getPotential() {
return potential;
}
public void setPotential(int potential) {
this.potential = potential;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int len = sc.nextInt();
List<Soldier> list = new ArrayList<Soldier>(len);
for(int i=0;i<len;i++){
Soldier soldier = new Soldier();
soldier.setCapacity(sc.nextInt());
soldier.setPotential(sc.nextInt());
list.add(i, soldier);
}
list.sort(new Comparator<Soldier>() {
@Override
public int compare(Soldier o1, Soldier o2) {
if(o1.getCapacity() == o2.getCapacity()){
return o2.getPotential()-o1.getPotential();
}
return o1.getCapacity() - o2.getCapacity();
}
});
//如果输入为空输出为0
if(list.size() == 0){
System.out.println(0);
}else if(list.size() == 1 || list.get(0).getCapacity() == list.get(list.size()-1).getCapacity()){
//如果只有一个战士,输出本身
//如果所有战士战力值相等,输出潜力值最高的
System.out.println(list.get(0).getCapacity()+list.get(0).getPotential());
}else{
//用战力值最高的战士去逐一决斗,累加所有的潜力
Soldier s = list.get(list.size()-1);
int c = s.getCapacity();
for(int i =0;i<list.size()-1;i++){
Soldier temp = list.get(i);
if(temp.getCapacity() >= temp.getPotential()){
//如果被决斗人战力大于或等于潜力,将不会被决斗
continue;
}
c = c+temp.getPotential() - temp.getCapacity();
}
System.out.println(c+s.getPotential());
}
sc.close();
}
}
要求:找出max(通过互相决斗之后新兵中战斗力值+潜力值). 获胜者战斗力 = (对手的潜力值 - 对手的战斗力值 )+ 自己的战斗力值 max(战斗力 + 潜力) = (对手的潜力值 - 对手的战斗力值 )+ (自己的战斗力值 + 自己的潜力值) 第一部分保证为正直,即 对手的潜力值 > 对手的战斗力值 if 本人 自己的潜力值 < 自己的战斗力值: max(战斗力 + 潜力) = max(对手的潜力值 - 对手的战斗力值 ) + (自己的战斗力值 + 自己的潜力值) 保证max(自己的战斗力值 + 自己的潜力值) else: max(战斗力 + 潜力) = max(对手的潜力值 - 对手的战斗力值 ) - (自己的潜力值 - 自己的战斗力值) + (自己的潜力值 + 自己的战斗力值) = max(对手的潜力值 - 对手的战斗力值 ) + 2 * 自己的战斗力值 保证 max(2 * 自己的战斗力值)
因此,求 max(自己的战斗力值 + 自己的潜力值),max(2 * 自己的战斗力值),max((对手的潜力值 - 对手的战斗力值 ), max1 = max(对手的潜力值 - 对手的战斗力值 ) + max(自己的战斗力值 + 自己的潜力值) max2 = max(对手的潜力值 - 对手的战斗力值 ) + max(2 * 自己的战斗力值) 最终结果:max(max1, max2)
#-*-coding:utf-8-*- n = int(raw_input())
lis = []
sum_zhan_qian = 0
max_zhan_qian = 0
max_zhan = 0
max_xin = 0
for i in xrange(0, n):
temp = raw_input()
[x, y] = map(int, temp.split())
lis.append([x, y])
if lis[i][0] < lis[i][1]:
sum_zhan_qian = sum_zhan_qian + lis[i][1] - lis[i][0]
temp = 2 * lis[i][0]
if temp > max_zhan:
max_zhan = temp
else:
temp = lis[i][0] + lis[i][1]
if temp > max_zhan_qian:
max_zhan_qian = temp
max_xin = sum_zhan_qian + max(max_zhan_qian, max_zhan)
print max_xin 对不住大家了,之前由于牛客测试样例问题有一种情况没有考虑到,虽然ac了但是ac不是
目的,我们要追求严谨性,吐曹一秒牛客的测试样例。这里贴出更改之后的代码,更改处
有标记,这里对大家说声抱歉,同时提醒大家注意排除所有情况以及对牛客的答案要仔细
思考。
/* ***********************************************
Author :wsw
Created Time :2017年05月21日 星期日 22时55分09秒
TASK :Algorithm/date/牛客网/GG/xunlianbudui.cpp
LANG :C++
************************************************ */
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <cmath>
#include <cstdlib>
#include <ctime>
using namespace std;
struct soder{
int x;
int y;
};
int comp(soder s1,soder s2)
{
return s1.x-s2.x!=0?s1.x<s2.x:s1.y<s2.y;
}
int main()
{
int n,z,q;
cin >> n;
soder ant[n];
for(int i=0;i<n;i++){
cin >> z >> q;
ant[i].x=z;
ant[i].y=q;
}
sort(ant,ant+n,comp);
int max = 0;
int index = 0;
int cha = 0;
for(int i=0;i<n;i++){
if(ant[i].x+ant[i].y>=max||ant[i].x+ant[i].y+cha>=max){
max = ant[i].x+ant[i].y;
cha = ant[i].y-ant[i].x;
index = i;
}
//此处判断战斗力相同情况下的情况
if(i>0&&ant[i].x==ant[i-1].x)
{
max = 0;
}
}
long res = max;
if(res>0){
for(int j = index-1;j>=0;j--){
if(ant[j].y>ant[j].x){
res += ant[j].y-ant[j].x;
}
}
cout << res << endl;
}else{
cout << 0 << endl;
}
return 0;
} /* ***********************************************
Author :wsw
Created Time :2017年05月21日 星期日 22时55分09秒
TASK :这道题其实思想很简单,需要点数学功底,搞明白潜力型的总值是固定的,只需要找到一个最合适的
战斗型人才就行 LANG :C++
************************************************ */
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <cmath>
#include <cstdlib>
#include <ctime>
using namespace std;
struct soder{
int x;
int y;
};
int comp(soder s1,soder s2)
{
return s1.x-s2.x!=0?s1.x<s2.x:s1.y<s2.y;
}
int main()
{
int n,z,q;
cin >> n;
soder ant[n];
for(int i=0;i<n;i++){
cin >> z >> q;
ant[i].x=z;
ant[i].y=q;
}
sort(ant,ant+n,comp);
//cout << " ssss " << endl;
int max = 0;
int index = 0;
int cha = 0;
for(int i=0;i<n;i++){
if(ant[i].x+ant[i].y>=max||ant[i].x+ant[i].y+cha>=max){
max = ant[i].x+ant[i].y;
cha = ant[i].y-ant[i].x;
index = i;
}
}
long res = max;
for(int j = index-1;j>=0;j--){
if(ant[j].y>ant[j].x){
res += ant[j].y-ant[j].x;
//cout << res << "+++" << endl;
}
}
cout << res << endl;
return 0;
}