您的位置:首页 > 其它

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

2017-07-26 19:45 519 查看
原题链接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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: