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;
}