cf 1288 D. Minimax Problem (好题)(二分+二进制表状态+枚举)

题意:

这题题目短,直接看英文更容易。

思路:
太久没做题了,没想出来。直接贴一份网上找的讲的清楚的思路好了。

来自 https://blog.csdn.net/Nothing_but_Fight/article/details/103985836

没错,虽然是好题,但是我这篇题解特水,主要是因为不是自己想的,热情减了三分了,再加上好晚了,我想睡觉了。。。

代码:

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <vector>
#include <math.h>
using namespace std;
typedef long long int ll;
const int maxn = 3e5 + 10;
const int maxm = 9;
const long double pi = acos(-1.0L);
const ll mod = 1e9 + 7;

int vis[1024];
int a[maxn][maxm],val[maxn];

int main(){
    int n,m;
    while(scanf("%d%d",&n,&m) != EOF){
        for(int i = 1;i <= n;i++){
            for(int j = 1;j <= m;j++){
                scanf("%d",&a[i][j]);
            }
        }
        int O = (1 << m) - 1;

        int l = 0,r = 1e9,mid,p1,p2;
        while(l <= r){
            mid = (l + r) >> 1;
            memset(vis,-1,sizeof(vis));
            for(int i = 1;i <= n;i++){
                int temp = 0;
                for(int j = 1;j <= m;j++){

                    if(a[i][j] < mid)
                        ;
                    else
                        temp++;
                    temp <<= 1;
                }
                temp >>= 1;
                val[i] = temp;
                vis[temp] = i;
            }
            int flag = 0;
            for(int i = 0;i <= O;i++){
                for(int j = 0;j <= O;j++){
                    if((i | j) == O && vis[i] != -1 && vis[j] != -1){
                        p1 = vis[i];
                        p2 = vis[j];
                        flag = 1;
                        break;
                    }
                }
                if(flag)
                    break;
            }
            if(flag){
                l = mid + 1;
            }
            else{
                r = mid - 1;
            }
        }
        printf("%d %d\n",p1,p2);
    }
    return 0;
}
View Code

猜你喜欢

转载自www.cnblogs.com/InitRain/p/12914069.html