Loading

CodeForces 1619D New Year's Problem

New Year's Problem

有n个人,m个商店,每个商店有n个物品,也有对应的\(a_i\),代表第i个人对这个物品的好感度。现在要求进入n-1个商店,为每个人购买一件物品,使得最后n个人中,获得物品的最低好感度最高

二分

一开始以为是贪心或者排序,没往二分上面想,想了半天的暴力也没想到有什么办法能够找到n-1家商店的情况

后来有人说是二分的时候,也没有什么头绪,因为不知道如何去检查一个答案是否正确

这里给出二分能够完成的原因:假设现在的值是X,当X大于最后的答案的时候,必然是不成立的;当X小于最后答案的时候,是可以成立的,因此他是一个单调的函数,可以使用二分来查找答案

如何检查答案是否正确:

  1. 因为是要在n-1个商店里面找因此首先得满足,至少有一家商店的商品的好感度大于等于X

  2. 因为是每个人都要收到礼物,因此每个人至少能收到一件大于等于X好感度的礼物

#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;
const int maxn = 1e5 + 10;
vector<int>gra[maxn];
int num[maxn];

int main()
{
    int t;
    scanf("%d", &t);
    while(t--)
    {
        int m, n;
        scanf("%d%d", &m, &n);
        for(int i=0; i<m; i++)
            gra[i].clear();
        for(int i=0; i<m; i++)
        {
            for(int j=0; j<n; j++)
            {
                int x;
                scanf("%d", &x);
                gra[i].push_back(x);
            }
        }
        
        int l = 1, r = 1e9 + 10;
        while(l < r)
        {
            int mid = l + r >> 1;
            bool flag = false;
            for(int i=0; i<n; i++)
                num[i] = 0;
            for(int i=0; i<m; i++)
            {
                int cnt = 0;
                for(int j=0; j<n; j++)
                {
                    if(gra[i][j] >= mid)
                    {
                        cnt++;
                        num[j]++;
                    }
                }
                if(cnt >= 2)
                    flag = true;
            }
            for(int i=0; i<n; i++)
                if(num[i] == 0)
                    flag = false;
            if(flag)
                l = mid + 1;
            else
                r = mid;
        }
        printf("%d\n", l - 1);
    }
    return 0;
}
posted @ 2022-04-25 17:04  dgsvygd  阅读(48)  评论(0编辑  收藏  举报