思路:这题有一特点虽然n很大,但是m很小,且最小值最大化–二分
二分check()怎么写?判断每两两数组得出的数组最小值是否可以大于等于mid;
怎么判断是关键----把每一个数组变成一个01串,若这位大于或等于mid则是1,否则是0,那么两个数组得出的数组的最小值要大于或等于mid,那么对这两个二进制作 | 运算,得到的应该是m个1
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int M = 9;
const int N = 3e5+10;
const int inf = 0x3f3f3f3f;
int a[N][M];
int n,m,ans1,ans2;
int num[300];//2^8-1 = 255
bool isOK(int x){
memset(num,0,sizeof(num));
for(int i = 0;i < n;i++){
int sum = 0;
for(int j = 0;j < m;j++){
if(a[i][j] >= x) sum+=(1<<j);
}
num[sum] = i+1;//记序号
}
for(int i = 0;i < (1<<m);i++){
for(int j = 0;j < (1<<m);j++){
if(num[i]&&num[j]&&(i|j)==(1<<m)-1){
ans1 = num[i];
ans2 = num[j];
return true;
}
}
}
return false;
}
int main(){
scanf("%d%d",&n,&m);
int r = -inf,l = inf;
for(int i = 0;i < n;i++){
for(int j = 0;j < m;j++){
scanf("%d",&a[i][j]);
r = max(r,a[i][j]);
l = min(l,a[i][j]);
}
}
int ans;
while(l <= r){
int mid = l+r>>1;
if(isOK(mid)){
l = mid+1;
ans = mid;
}else r = mid-1;
}
isOK(ans);
printf("%d %d\n",ans1,ans2);
return 0;
}
来源:CSDN
作者:weixin_44083561
链接:https://blog.csdn.net/weixin_44083561/article/details/104144988