Codeforces Round #762 (Div. 3) D. New Year‘s Problem

题目链接:https://codeforces.com/contest/1619/problem/D

题目大意
张三有 n n n 个朋友,要在 m m m 个商店中选一些商店给他的朋友买礼物(最多选 n − 1 n-1 n1个商店),要求每个朋友都要收到礼物。
在第 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 n2 个商店为另外的 n − 2 n-2 n2 个朋友购买礼物。(ps:也可以继续在第 x x x 个商店给其他朋友买礼物,所以直接取 max 即可)
设另外 n − 2 n-2 n2 个朋友得到礼物快乐值的最小值为 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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值