Educational Codeforces Round 80 (Div. 2) D題 Minimax Problem (二分 + 二進制枚舉)

題目

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

發佈了184 篇原創文章 · 獲贊 24 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章