zoukankan      html  css  js  c++  java
  • D. Minimax Problem Codeforces 1288D binary_search+二进制

    题目大意:n*m的矩阵中,找到两行数,可以形成两个一维数组,数组1的位置i和数组2的位置i去最大构成新数组b的元素b[i],最终目的要使数组b中最小的数尽可能的大

    题解:

      m的范围是(1,8),比较小,我们用二分答案加按位与或来做,维护一个二维数组,当arr[i][j]>=x时,记为1,否则记为0。所以每一行最多有8个数,也就是最多会有pow(2,8)=256种答案。然后对这些数保留与或就行了,时间复杂度logx(max)*(n*m)

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const ll INF=1e9+7;
    const ll N=3E5+7;
    ll arr[N][10];
    ll mark[N][10];
    ll goal=0;
    ll cnt[N];
    ll mp[N];
    ll n,m;
    ll ans1=0,ans2=0;
    bool check(ll x){
        memset(mark,0,sizeof(mark));
        memset(mp,0,sizeof mp);
        for(ll i=1;i<=n;i++){
            for(ll j=1;j<=m;j++){
                if(arr[i][j]>=x) mark[i][j]=1;
                else mark[i][j]=0;
            }
        }
        ll pos=0;
        for(ll i=1;i<=n;i++){
            ll c=0;
            for(ll j=1;j<=m;j++){
                if(mark[i][j]){
                    c+=1<<(j-1);
                }
            }
            if(!mp[c]){
                mp[c]=i;
                cnt[pos++]=c;
            }
        }
        if(pos==1){
            if(cnt[0]==goal){
                ans1=mp[goal];
                ans2=mp[goal];
                return 1;
            }
            else return 0;
        }
        for(ll i=0;i<pos;i++)
            for(ll j=i+1;j<pos;j++){
                if((cnt[i]|cnt[j])==goal) {
                    ans1=mp[cnt[i]];
                    ans2=mp[cnt[j]];
                    return 1;
                }
            }
        return 0;
    
    }
    int  main(){
        ios::sync_with_stdio(false );
        cin>>n>>m;
        ll left=INF,right=0;
        for(ll i=1;i<=n;i++){
            for(ll j=1;j<=m;j++){
                cin>>arr[i][j];
                left=min(left,arr[i][j]);
                right=max(right,arr[i][j]);
            }
        }
        for(ll i=0;i<m;i++) goal+=1<<i;
        int ansa=-1,ansb=-1;
        while(left<=right){
            ll mid=(left+right)/2;
            if(check(mid)){
                left=mid+1;
                ansa=ans1;
                ansb=ans2;
            }
            else right=mid-1;
        }
        cout<<ansa<<" "<<ansb<<endl;
        return 0;
    }
  • 相关阅读:
    Delphi中 StrToIntDef函数的用法:
    Delphi判断文件夹(目录)是否存在,不存在就创建一个,可以一次创建多级目录
    Delphi中Format的字符串格式化使用说明
    linux下可变参数打印
    c++11 thread
    QMessageBox 使用
    Ubuntu虚拟机配置nfs
    test
    Qt 布局时组建不贴边
    QPainter 居中写字
  • 原文地址:https://www.cnblogs.com/Accepting/p/12232631.html
Copyright © 2011-2022 走看看