例题
1. [THUPC 2023 初赛] 众数
题目描述
你有若干个 [ 1 , n ] [1,n] [1,n] 内的正整数:对于 1 ≤ i ≤ n 1 \le i \le n 1≤i≤n,你有 a i a_i ai 个整数 i i i。设 S = ∑ i = 1 n a i S = \sum_{i=1}^n a_i S=∑i=1nai。
对于一个序列 p 1 , p 2 , ⋯ , p l p_1,p_2,\cdots,p_l p1,p2,⋯,pl,定义其众数 maj ( p 1 , p 2 , ⋯ , p l ) \text{maj}(p_1,p_2,\cdots,p_l) maj(p1,p2,⋯,pl) 为出现次数最多的数。若有多个数出现次数最多,则其中最大的数为其众数。
现在你需要把这 S S S 个数排成一个序列 b 1 , b 2 , ⋯ , b S b_1,b_2,\cdots,b_S b1,b2,⋯,bS,使得 ∑ i = 1 S maj ( b 1 , b 2 , ⋯ , b i ) \sum_{i=1}^S \text{maj}(b_1,b_2,\cdots,b_i) ∑i=1Smaj(b1,b2,⋯,bi) 最大。输出该最大值。
输入格式
第一行一个整数 n n n,表示值域。
接下来一行 n n n 个正整数 a 1 , a 2 , ⋯ , a n a_1,a_2,\cdots,a_n a1,a2,⋯,an,表示每种数的个数。
输出格式
输出一行一个正整数表示 ∑ i = 1 S maj ( b 1 , b 2 , ⋯ , b i ) \sum_{i=1}^S \text{maj}(b_1,b_2,\cdots,b_i) ∑i=1Smaj(b1,b2,⋯,bi) 的最大值。
样例1
输入
3 1 3 2输出
17
#include <iostream>
#include <algorithm>
using namespace std;
int n;
int ans, maxn;
int a[100005];
int f[100005];
int main() {
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
for (int i = n; i >= 1; i--) {
while (maxn < a[i]) {
maxn++;
f[maxn] = f[maxn-1]+i;
}
ans += f[a[i]];
}
cout << ans;
return 0;
}
2. 寻找平面上的极大点
题目描述
在一个平面上,如果有两个点 ( x , y ) , ( a , b ) (x,y),(a,b) (x,y),(a,b),如果说 ( x , y ) (x,y) (x,y) 支配了 ( a , b ) (a,b) (a,b),这是指 x ≥ a , y ≥ b x\ge a,y\ge b x≥a,y≥b;
用图形来看就是 ( a , b ) (a,b) (a,b) 坐落在以 ( x , y ) (x,y) (x,y) 为右上角的一个无限的区域内。
给定 n n n 个点的集合,一定存在若干个点,它们不会被集合中的任何一点所支配,这些点叫做极大值点。
编程找出所有的极大点,按照 x x x 坐标由小到大,输出极大点的坐标。
输入描述
输入包括两行,第一行是正整数 n n n,表示是点数,第二行包含 n n n 个点的坐标,坐标值都是整数,坐标范围从 0 ∼ 100 0\sim100 0∼100,输入数据中不存在坐标相同的点。
输出描述
按 x x x 轴坐标最小到大的顺序输出所有极大点。
输出格式为: ( x 1 , y 1 ) , ( x 2 , y 2 ) , ⋯ , ( x k , y k ) (x_1,y_1),(x_2,y_2),\cdots,(x_k,y_k) (x1,y1),(x2,y2),⋯,(xk,yk)
注意:输出的每个点之间有","分隔,最后一个点之后没有",",少输出和多输出都会被判错。
样例1
输入
5 1 2 2 2 3 1 2 3 1 4输出
(1,4),(2,3),(3,1)
提示
对于 50 % 50\% 50% 的数据: 1 ≤ N ≤ 100 1≤N≤100 1≤N≤100; 0 ≤ X , Y ≤ 100000 0≤X,Y≤100000 0≤X,Y≤100000;
对于 100 % 100\% 100% 的数据: 1 ≤ N ≤ 500000 1≤N≤500000 1≤N≤500000; 0 ≤ X , Y ≤ 100000 0≤X,Y≤100000 0≤X,Y≤100000。
#include <iostream>
#include <algorithm>
using namespace std;
int n;
struct Node {
int x, y;
}a[250100];
bool cmp(Node aa, Node bb) {
if (aa.y == bb.y) return aa.x > bb.x;
return aa.y > bb.y;
}
int main() {
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i].x >> a[i].y;
}
sort(a+1, a+n+1, cmp);
int xx = a[1].x;
cout << "(" << a[1].x << "," << a[1].y << ")";
for (int i = 1; i <= n; i++) {
if (a[i].x > xx) {
cout << ",(" << a[i].x << "," << a[i].y << ")";
xx = max(xx, a[i].x);
}
}
return 0;
}
3. 奶牛杂技团
题目描述
农夫约翰有 N N N 头奶牛,编号从 1 ∼ N 1\sim N 1∼N,打算进行叠罗汉的杂技表演。
进行叠罗汉表演时,奶牛站在彼此的身上,形成一个有一定高度的垂直堆叠。
奶牛们正在试图弄清楚它们在这个堆叠中的位置顺序。
奶牛们有自己的重量 W i W_i Wi 和力量 S i S_i Si,一头奶牛倒下的风险等于它身上所有奶牛(不包括它自己)的重量和减去它的力量。
你的任务是确定奶牛的顺序,使奶牛的风险值中的最大值尽可能小。
输入描述
第一行包括一个整数 N N N,表示奶牛的数量,其中 1 ≤ N ≤ 50000 1≤N≤50000 1≤N≤50000。
接下来 N N N 行,每行两个整数,表示奶牛的重量 W i W_i Wi 和力量 S i S_i Si,其中 1 ≤ W i ≤ 10000 1≤W_i≤10000 1≤Wi≤10000, 1 ≤ S i ≤ 1 0 9 1≤S_i≤10^9 1≤Si≤109。
输出描述
输出一个整数,表示最大风险值的最小可能值。
样例1
输入
3 10 3 2 5 3 3输出
2
#include <iostream>
#include <algorithm>
using namespace std;
long long n, z;
long long m = -2e7, cnt;
struct Node {
int s, w;
} b[50005];
bool cmp(Node x, Node y) {
return x.s+x.w < y.s+y.w;
}
int main() {
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> b[i].w >> b[i].s;
}
sort(b+1, b+n+1, cmp);
for(int i = 1; i <= n; i++) {
m = max(m, (long long)cnt-b[i].s);
cnt += b[i].w;
}
cout << m;
return 0;
}
1494

被折叠的 条评论
为什么被折叠?



