題目
http://codeforces.com/contest/1288/problem/D
題意
n個數組,每個數組都有m個數據
要你找到這樣兩個數組ai 和 aj,使得也就是使那個最小值是最大的。
思路
首先根據題意,我們可以知道目的是要讓最小值最大化,二分能夠解決該類問題(可見我搜索算法欄目裏面的二分總結博客)。
這裏要注意是我們只能二進制枚舉列,而不是二進制枚舉行,一開始想的是二分答案然後直接枚舉 行,導致TLE。
行數多,列數少,稍微變通一下即可。
代碼
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 3e5 + 10;
int n, m;
int vis[maxn];
int a[maxn][10];
int ans1, ans2;
bool check(int mid)
{
memset(vis, 0, sizeof(vis));
for(int i = 1; i <= n; i++)
{
int tem = 0;//列的二進制
for(int j = 1; j <= m; j++)
if(a[i][j] >= mid)
tem |= (1 << j - 1);
vis[tem] = i;
}
int mx = pow(2, m);//枚舉列
for(int i = 0; i <= mx; i++)
for(int j = i; j <= mx; j++)//初始化j = i
if(vis[i] && vis[j] && (i | j) == (1 << m) - 1)//當枚舉到所有列滿足>=mid的情況時
{
ans1 = vis[i], ans2 = vis[j];
return true;
}
return false;
}
int main()
{
cin >> n >> m;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
cin >> a[i][j];
int l = 0, r = 1e9, mid;
while(l <= r)
{
mid = l + r >> 1;
if(check(mid))
l = mid + 1;
else
r = mid - 1;
}
cout << ans1 << " " << ans2;
return 0;
}
參考來源
https://blog.csdn.net/ln2037/article/details/103993388