CodeForces - 514D :R2D2 and Droid Army(二分、暴力)

原题链接CodeForces - 514D

题意:有n个机器排成一列,每个机器有m种类型的描述,每种类型的描述包括a个细节,现在你有m种类型的武器,可以射击k次,第i种武器一次可以摧毁该列所有机器的第i种类型的一个细节,当一个机器的所有细节都被摧毁即被消灭了,问各种类型分别射击多少次才能使连续消灭的机器的长度最大

思路:将每种类型的细节数记录到multiset中,对同一行的各列求和,判断是否满足小于最大射击次数,然后暴力选出最大的区间,并记录该区间各列的最大值,即各种类型的射击次数
也有人用RMQ预处理+二分~

AC代码

//思路:将每种类型的细节数记录到multiset中,对同一行的各列求和,判断是否满足小于最大射击次数,
//然后暴力选出最大的区间,并记录该区间各列的最大值,即各种类型的射击次数

#include<iostream>
#include<cstdio>
#include<set>
#include<algorithm>
using namespace std;
#define maxn 100100
multiset<int>s[10];
int a[maxn][10],b[10];

int main()
{
    int n,m,k;
    scanf("%d%d%d",&n,&m,&k);
    for(int i=0; i<n; i++)
        for(int j=0; j<m; j++)
            scanf("%d",&a[i][j]);
    int cnt=0;
    for(int q=0,j=0; j<n; j++)
    {
       // int  q=0;
        for(int i=0; i<m; i++)
            s[i].insert(a[j][i]);          //s[i]储存m种类型各自的detail数量,这里利用set自动排序的特点,最顶层是最大值
        while(q<=j)
        {
            int sum=0;
            for(int i=0; i<m; i++)
                sum+=*s[i].rbegin();     //rbegin()返回倒数第一个数,即最顶层的数
            if(sum<=k) break;             //判断最顶层的细节总数是否小于最大射击次数k,如果小于则从q~j的序列都能被消灭
            for(int i=0; i<m; i++)           //否则接下来就将其擦除
                s[i].erase(s[i].find(a[q][i]));
            q++;
        }
        if(cnt<j-q+1)
        {
            cnt=j-q+1;                    //cnt表示当前长度,如果找到了更长的序列就替换
            for(int i=0; i<m; i++)
                b[i]=*s[i].rbegin();
        }
    }
    for(int i=0; i<m; i++)
    {
        if(i) putchar(' ');
        printf("%d",b[i]);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值