训练部队--全国模拟(三)

[编程题] 训练部队

时间限制:1秒

空间限制:32768K

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

输入描述:

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

输出描述:

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

输入例子:

2 1 2 2 1

输出例子:

4

解题思路:

可以考虑把新兵分为两种类型。

一种战斗型(战斗值大于潜力值的),一种潜力型(相当于打了他可以获得潜力值),对潜力型的新兵进行战斗力值排序。

然后一种情况是潜力型中战斗值最高的牛牛去打完剩余的潜力型,因为战斗力值会越大越多,另一种情况考虑打完所有潜力型获得值是固定的,那么在攻击型中找一个能打完所有的潜力型的牛牛,并且战斗力值和潜力值要最大。

实现就是用的前缀和和二分

 1 #include <bits/stdc++.h>
 2
 3 using namespace std;
 4
 5 typedef long long LL;
 6 const int maxn = 100005;
 7 int n;
 8 int goodn,badn;
 9 LL sum[maxn],MAX[maxn];
10 struct Node {
11     LL x,y;
12     Node() {}
13     Node (const LL &_x,const LL &_y) { x=_x; y=_y; }
14     bool operator < (const Node &t) const {
15         if(x ^ t.x) return x < t.x;
16         return y < t.y;
17     }
18 }good[maxn],bad[maxn];
19 int search(int L, int R, LL x) {
20     while(L < R) {
21         int mid = (L + R + 1) >> 1;
22         if(MAX[mid] < x) L = mid;
23         else R = mid - 1;
24     }
25     return L;
26 }
27 LL solve() {
28     LL ans = 0;
29     ans = max(ans, sum[search(0, goodn - 1, good[goodn].x)] + good[goodn].x + good[goodn].y);
30     for(int i = 1; i <= badn; i++) {
31         int pos = search(0, goodn, bad[i].x);
32         ans = max(ans, sum[pos] + bad[i].x + bad[i].y);
33     }
34     return ans;
35 }
36 int main() {
37     scanf("%d", &n);
38     for(int i = 1; i <= n; i++) {
39         LL x, y;
40         scanf("%lld%lld",&x, &y);
41         if(x < y) good[++goodn] = Node(x,y);
42         else bad[++badn] = Node(x,y);
43     }
44     sort(good + 1, good + goodn + 1);
45     MAX[0] = 0; sum[0] = 0;
46     for(int i = 1; i <= goodn; i++) {
47         sum[i] = sum[i-1] + good[i].y - good[i].x;
48         MAX[i] = max(MAX[i-1], good[i].x - sum[i-1]);
49     }
50     LL ans = solve();
51     printf("%lld\n", ans);
52     return 0;
53 }

引自:https://www.nowcoder.com/discuss/27498?type=0&order=0&pos=4&page=1

时间: 2024-08-29 21:17:21

训练部队--全国模拟(三)的相关文章

c语言:模拟三次密码输入。

模拟三次密码输入. 解:程序: #include<stdio.h> #include<windows.h> #include<string.h> int main() { int i; char *p = "123456"; char arr[10]; for (i = 0; i < 3; i++) { printf("请输入密码:"); scanf("%s",arr); if (strcmp(p,arr

组队竞赛--全国模拟(三)

[编程题] 组队竞赛 牛牛举办了一次编程比赛,参加比赛的有3*n个选手,每个选手都有一个水平值a_i.现在要将这些选手进行组队,一共组成n个队伍,即每个队伍3人.牛牛发现队伍的水平值等于该队伍队员中第二高水平值. 例如: 一个队伍三个队员的水平值分别是3,3,3.那么队伍的水平值是3 一个队伍三个队员的水平值分别是3,2,3.那么队伍的水平值是3 一个队伍三个队员的水平值分别是1,5,2.那么队伍的水平值是2 为了让比赛更有看点,牛牛想安排队伍使所有队伍的水平值总和最大. 如样例所示: 如果牛牛

排序子序列--全国模拟(三)

牛牛定义排序子序列为一个数组中一段连续的子序列,并且这段子序列是非递增或者非递减排序的.牛牛有一个长度为n的整数数组A,他现在有一个任务是把数组A分为若干段排序子序列,牛牛想知道他最少可以把这个数组分为几段排序子序列. 如样例所示,牛牛可以把数组A划分为[1,2,3]和[2,2,1]两个排序子序列,至少需要划分为2个排序子序列,所以输出2 输入描述: 输入的第一行为一个正整数n(1 ≤ n ≤ 10^5) 第二行包括n个整数A_i(1 ≤ A_i ≤ 10^9),表示数组A的每个数字. 输出描述

添加字符--全国模拟(三)

[编程题] 添加字符 时间限制:1秒 空间限制:32768K 牛牛手里有一个字符串A,羊羊的手里有一个字符串B,B的长度大于等于A,所以牛牛想把A串变得和B串一样长,这样羊羊就愿意和牛牛一起玩了. 而且A的长度增加到和B串一样长的时候,对应的每一位相等的越多,羊羊就越喜欢.比如"abc"和"abd"对应相等的位数为2,为前两位. 牛牛可以在A的开头或者结尾添加任意字符,使得长度和B一样.现在问牛牛对A串添加完字符之后,不相等的位数最少有多少位? 输入描述: 第一行为

变换次数--全国模拟(三)

[编程题] 变换次数 时间限制:1秒 空间限制:32768K 牛牛想对一个数做若干次变换,直到这个数只剩下一位数字. 变换的规则是:将这个数变成 所有位数上的数字的乘积.比如285经过一次变换后转化成2*8*5=80. 问题是,要做多少次变换,使得这个数变成个位数. 输入描述: 输入一个整数.小于等于2,000,000,000. 输出描述: 输出一个整数,表示变换次数. 输入例子: 285 输出例子: 2 解题思路:针对于给定的数 1)求出数的每一位,且相乘存入result中 2)一次操作后co

数组变换--全国模拟(三)

[编程题] 数组变换 时间限制:1秒 空间限制:32768K 牛牛有一个数组,里面的数可能不相等,现在他想把数组变为:所有的数都相等.问是否可行. 牛牛可以进行的操作是:将数组中的任意一个数改为这个数的两倍. 这个操作的使用次数不限,也可以不使用,并且可以对同一个位置使用多次. 输入描述: 输入一个正整数N (N <= 50) 接下来一行输入N个正整数,每个数均小于等于1e9. 输出描述: 假如经过若干次操作可以使得N个数都相等,那么输出"YES", 否则输出"NO&q

神奇数--全国模拟(三)

[编程题] 神奇数 时间限制:1秒 空间限制:32768K 给出一个区间[a, b],计算区间内"神奇数"的个数. 神奇数的定义:存在不同位置的两个数位,组成一个两位数(且不含前导0),且这个两位数为质数. 比如:153,可以使用数字3和数字1组成13,13是质数,满足神奇数.同样153可以找到31和53也为质数,只要找到一个质数即满足神奇数. 输入描述: 输入为两个整数a和b,代表[a, b]区间 (1 ≤ a ≤ b ≤ 10000). 输出描述: 输出为一个整数,表示区间内满足条

编程成长日记————模拟三次输入密码

简单的模拟取钱时输入密码: #include<stdio.h> #include<windows.h> #include<string.h> int main () { int i=0; int n=2; char passwd[10]; char *p="123456"; for (i=0;i<3;i++) { printf("请输入密码:\n");     scanf("%s",passwd); if

【编程训练-考研上机模拟】综合模拟1-2019浙大上机模拟(晴神)

3月9日综合模拟 A - 古剑奇谭三:封印解除 Problem Description 众所周知,在游戏<古剑奇谭三>中一种被封印的宝箱,而解除封印的过程则是一个小游戏,在这个小游戏中有一个圆盘,如下图所示.为了简单起见,本题只考虑这个小游戏初见时的最简单规则,后续随着游戏主线的推进,这个小游戏会产生好几种变体,转来转去的,会加大本题难度,所以都不考虑了. 可以看到这个圆盘的上下左右各有一块扇状碎片,这四块碎片是可以进出圆盘内外的,而游戏的目标则是让玩家操作上下左右按键,来让这四块扇形最终都处