Codeforces 1288D Minimax Problem

题目链接:

Codeforces 1288D Minimax Problem

思路:

1.我们二分这个最小最大值,每次判断这个值可不可以;
2.对于一个数组,一共有八个数字,如果这个数字大于当前二分的值,就设为1,否则为0,那么一个数组就可以转化为八个0/1,组合起来就变成一个小于等于255的二进制数,如果有两个数组它们转换出来的数相异或,值为255,就说明这两个数组可以合成当前二分值。
3.注意不要用所有数组两两异或去比较,一共就小于255个情况,我们去两个循环遍历这些情况即可;

代码:

#include<bits/stdc++.h>

using namespace std;

const int maxn = 3e5 + 5;
const int maxm = 10;
const int N = 255;
int n, m, a[maxn][maxm], x, y, ans[N + 10];

bool ok(int k){
	memset(ans, 0, sizeof(ans));
	for(int i = 1; i <= n ; i++) {
		int t = 0;
		for(int j = 1; j <= m; j++){
			if(a[i][j] >= k) t |= (1 << (j - 1));
		}
		ans[t] = i;
	}
	for(int i = 0; i <= N; i++){
		if(ans[i] == 0) continue;
		for(int j = i; j <= N; j++){
			if(ans[j] && (i | j) == (1 << m) - 1) {
				x = ans[i], y = ans[j];
				return true;
			}
		}
	}
	return false;
}

int main() {
#ifdef MyTest
	freopen("Sakura.txt", "r", stdin);
#endif	
	scanf("%d %d", &n, &m);
	for(int i = 1; i <= n; i++) {
		for(int j = 1; j <= m; j++) scanf("%d", &a[i][j]);	
	}
	int lf = 0, rt = 1e9;
	while(lf <= rt) {
		int mid = (lf + rt) >> 1;
		if(ok(mid)) lf = mid + 1;
		else rt = mid - 1;	
	}
	cout << x << ' ' << y;
	return 0;
}
原文地址:https://www.cnblogs.com/yuhan-blog/p/12308681.html