题目链接:https://codeforces.com/contest/1619/problem/D
题目大意
张三有
n
n
n 个朋友,要在
m
m
m 个商店中选一些商店给他的朋友买礼物(最多选
n
−
1
n-1
n−1个商店),要求每个朋友都要收到礼物。
在第
i
i
i 个商店给第
j
j
j 个朋友买礼物时,朋友的快乐值为
p
i
,
j
p_{i,j}
pi,j。
设最终第
j
j
j 个朋友的快乐值为
a
j
a_j
aj,定义
α
=
m
i
n
(
a
1
,
a
2
,
…
,
a
n
)
α = min(a_1,a_2,…,a_n)
α=min(a1,a2,…,an),求最大的
α
α
α 的值。
思路
至少在一家商店购买两个(或更多)的礼物即可。
假如在第
x
x
x 个商店为朋友
a
a
a 和
b
b
b 购买礼物,那么需要再选
n
−
2
n-2
n−2 个商店为另外的
n
−
2
n-2
n−2 个朋友购买礼物。(ps:也可以继续在第
x
x
x 个商店给其他朋友买礼物,所以直接取 max 即可)
设另外
n
−
2
n-2
n−2 个朋友得到礼物快乐值的最小值为
Z
Z
Z,这时的
α
=
m
i
n
(
p
x
,
a
,
p
x
,
b
,
Z
)
α = min(p_{x,a}, p_{x,b}, Z)
α=min(px,a,px,b,Z)
AC代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn = 1e5 + 5;
vector<int> mx;
vector<int> a[maxn];
int main(){
int ncase;
scanf("%d", &ncase);
while(ncase--){
int n, m;
scanf("%d %d", &m, &n);
int num;
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
scanf("%d", &num);
a[i].push_back(num);
}
}
for(int i = 0; i < n; i++) mx.push_back(a[0][i]);
for(int i = 1; i < m; i++){
for(int j = 0; j < n; j++){
mx[j] = max(mx[j], a[i][j]);
}
}
int res = 0;
for(int i = 0; i < m; i++){
int mx1 = 0, pos1 = 0;
int mx2 = 0, pos2 = 0;
for(int j = 0; j < n; j++){
if(a[i][j] > mx1){
mx2 = mx1, pos2 = pos1;
mx1 = a[i][j], pos1 = j;
}
else if(a[i][j] > mx2){
mx2 = a[i][j], pos2 = j;
}
}
int ans = mx2; // 选出第 i 个商店的前两大
for(int j = 0; j < n; j++){ // 计算其他 n-2 个朋友得到的快乐值
if(j == pos1 || j == pos2) continue;
int tmp = mx[j];
ans = min(ans, tmp);
}
res = max(res, ans);
}
cout << res << endl;
for(int i = 0; i < m; i++) a[i].clear();
mx.clear();
}
return 0;
}