Educational Codeforces Round 80 (Rated for Div. 2) D. Minimax Problem

題目鏈接

題目意思:

n*m的數組, 選取兩行,兩行合併成一行,取對應位置上的最大值,然後再取這行的最小值。使這個最小值最大,問這兩行的行號。
每行的數字最多八個,

思路:

看到每行最多八個數, 就要想到二進制位優化。

首先要二分出來最大的數 x ,
對於這個數,我們進行check。
然後對於每一行, 這一行中如果大於 x, 就設爲1, 否則就設爲 0, 這樣每行就可以組成一個數 y 。vis[y] = i;
這個數最大就是256 , 就可以兩重for循環,然後暴力判斷這兩行是不是滿足條件。
判斷的標準就是 if (vis[i] && vis[j] && (i|j) == (1 << m) - 1)

反思:

太巧妙了emmmm

#include<bits/stdc++.h>
using namespace std;
const int N = 3e5+100;
int a[N][10],n,m,ans1,ans2;
int vis[500];
bool fuck(int x){
	int tmp;
	memset(vis, 0, sizeof vis);
	for (int i = 1; i <= n; ++i){
		tmp = 0;
		for (int j = 1; j <= m; ++j){
			if (a[i][j] >= x) tmp |= (1 << (j - 1));
		}
		vis[tmp] = i;
	}
	int mx = 1 << m;
	for (int i = 0; i < mx; ++i){
		for (int j = 0; j < mx; ++j){
			if (vis[i] && vis[j] && (i|j) == (1 << m) - 1) {
				ans1 = vis[i], ans2 = vis[j];
				return 1;
			}
		}
	}
	return 0;
}
int main(){
	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 l = 0, r = 1e9, mid;
	while(l <= r){
		mid = (l + r) >> 1;
		if (fuck(mid)) l = mid + 1; else r = mid - 1;
	}	
	printf("%d %d\n",ans1, ans2);
	return 0;
}
發佈了237 篇原創文章 · 獲贊 13 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章