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