【codeforces】Educational Codeforces Round 80 D. Minimax Problem——二分+二进制处理

题目链接

题目大意

有n个维度为m的向量,取其中两个进行合并,合并时每个维度取两者之间的较大者,得到的新的向量中,维度值最小者最大为多少

分析

首先最需要注意的是m的取值,m最大只有8
那么我们可以二分答案,对于每一个二分值,进行下面的操作
将整个矩阵的每一个元素,如果这个元素大于二分值,则变成1,反正则变成0
把每一个向量压缩为单个二进制数
这样我们最多只会得到\(2^8 = 256\)种不同的二进制数,然后暴力的遍历所有可能的二进制数的组合,得到是否满足当前二分值

AC code

#include <bits/stdc++.h>

using namespace std;

const int NUM = 3e5 + 100;

int data[NUM][10];

bool check(int value, int n, int m, pair<int, int> &ans) {
    map<unsigned, int> s;
    for (int i = 0; i < n; ++i) {
        unsigned temp = 0;
        for (int j = 0; j < m; ++j) {
            temp <<= 1u;
            temp |= data[i][j] > value;
        }
        s.insert({temp, i});
    }
    unsigned tar = -1u >> (sizeof(int) * 8 - m);
    for (auto iter1 = s.begin(); iter1 != s.end(); ++iter1) {
        for (auto iter2 = iter1; iter2 != s.end(); ++iter2) {
            if ((iter1->first | iter2->first) == tar) {
                ans.first = iter1->second;
                ans.second = iter2->second;
                return true;
            }
        }
    }
    return false;
}

void solve() {
    int n, m;
    cin >> n >> m;
    int l = INT_MAX, r = 0;
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            cin >> data[i][j];
            l = min(l, data[i][j]);
            r = max(r, data[i][j]);
        }
    }
    int mid, cnt = r - l;
    pair<int, int> ans;
    while (cnt > 0) {
        int step = cnt / 2;
        mid = l + step;
        if (check(mid, n, m, ans)) {
            l = mid + 1;
            cnt -= step + 1;
        } else
            cnt /= 2;
    }
    cout << ans.first + 1 << " " << ans.second + 1 << endl;
}

signed main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
#ifdef ACM_LOCAL
    freopen("in.txt", "r", stdin);
    freopen("out.txt", "w", stdout);
    long long test_index_for_debug = 1;
    char acm_local_for_debug;
    while (cin >> acm_local_for_debug) {
        cin.putback(acm_local_for_debug);
        if (test_index_for_debug > 20) {
            throw runtime_error("Check the stdin!!!");
        }
        auto start_clock_for_debug = clock();
        solve();
        auto end_clock_for_debug = clock();
        cout << "Test " << test_index_for_debug << " successful" << endl;
        cerr << "Test " << test_index_for_debug++ << " Run Time: "
             << double(end_clock_for_debug - start_clock_for_debug) / CLOCKS_PER_SEC << "s" << endl;
        cout << "--------------------------------------------------" << endl;
    }
#else
    solve();
#endif
    return 0;
}

原文地址:https://www.cnblogs.com/mauve-hkq/p/12293352.html

时间: 2024-10-09 04:33:29

【codeforces】Educational Codeforces Round 80 D. Minimax Problem——二分+二进制处理的相关文章

Educational Codeforces Round 80. D - Minimax Problem

题面:https://codeforces.com/contest/1288/problem/D 题目大意: 给定n个序列,每个序列元素个数严格相等于m 你需要找到两个序列a[i]和a[j],使其每个对应位置的元素取大后得到b序列  b[k]=max(a[i][k],a[j][k]) 且让b序列中的最小值最大 i可以等于j 解题思路: 二分假设这个b序列的最小值的值x 将a序列转化成01构成的二进制串存在数组b中 0表示当前位置的值<x 1表示当前位置的值>=x 每次便最多可以得到3e5个字符

Codeforces Educational Codeforces Round 44 (Rated for Div. 2) E. Pencils and Boxes

Codeforces Educational Codeforces Round 44 (Rated for Div. 2) E. Pencils and Boxes 题目连接: http://codeforces.com/contest/985/problem/E Description Mishka received a gift of multicolored pencils for his birthday! Unfortunately he lives in a monochrome w

Codeforces Educational Codeforces Round 15 C. Cellular Network

C. Cellular Network time limit per test 3 seconds memory limit per test 256 megabytes input standard input output standard output You are given n points on the straight line — the positions (x-coordinates) of the cities and m points on the same line

codeforces Educational Codeforces Round 5 A. Comparing Two Long Integers

题目链接:http://codeforces.com/problemset/problem/616/A 题目意思:顾名思义,就是比较两个长度不超过 1e6 的字符串的大小 模拟即可.提供两个版本,数组版本 & 指针版本. (1)数组版本(短的字符串从高位处补0,直到跟长的字符串长度相同) 1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <cstring>

Codeforces Educational Codeforces Round 54 题解

题目链接:https://codeforc.es/contest/1076 A. Minimizing the String 题意:给出一个字符串,最多删掉一个字母,输出操作后字典序最小的字符串. 题解:若存在一个位置 i 满足 a[i] > a[i+1],若不删除 a[i] 则后续操作不可能更优. 1 #include <bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 #define ull unsigned

(最小生成树)Codeforces Educational Codeforces Round 9 Magic Matrix

You're given a matrix A of size n?×?n. Let's call the matrix with nonnegative elements magic if it is symmetric (so aij?=?aji), aii?=?0 and aij?≤?max(aik,?ajk) for all triples i,?j,?k. Note that i,?j,?k do not need to be distinct. Determine if the ma

(KMP、dp)Codeforces Educational Codeforces Round 21 G-Anthem of Berland

Berland has a long and glorious history. To increase awareness about it among younger citizens, King of Berland decided to compose an anthem. Though there are lots and lots of victories in history of Berland, there is the one that stand out the most.

codeforces Educational Codeforces Round 2 C Make Palindrome

C. Make Palindrome A string is called palindrome if it reads the same from left to right and from right to left. For example "kazak", "oo", "r" and "mikhailrubinchikkihcniburliahkim" are palindroms, but strings &quo

[Codeforces]Educational Codeforces Round 37 (Rated for Div. 2)

Water The Garden #pragma comment(linker, "/STACK:102400000,102400000") #include<stdio.h> #include<string.h> #include<stdlib.h> #include<vector> #include<algorithm> #include<iostream> #include<map> #inclu