题目:CF873C Strange Game On Matrix
双指针 - 贪心 - 前缀和
一道很简单的双指针题目,只不过是在矩阵上进行的, O ( n 2 ) O(n^2) O(n2) 就可以搞定
对于这道题,题目已经给定了区间长度,没有平常的双指针那么复杂,直接枚举区间就可以了
枚举矩阵每一列,并维护出前缀和数组
s
s
s
对于一个区间
[
l
,
r
]
[l,r]
[l,r] (保证长度为
k
k
k),取这个区间的得分就为
s
r
−
s
l
−
1
s_r-s_{l-1}
sr−sl−1 (区间中
1
\texttt1
1 的个数),那么为了获得这个区间而在这一列去掉的
1
\texttt1
1 的个数就为
s
l
−
1
s_{l-1}
sl−1(区间前
1
\texttt1
1 的个数)
AC代码
#include<cstdio>
#include<iostream>
using namespace std;
const int Maxn=110;
int a[Maxn][Maxn],s[Maxn];
int ans,tot;
int n,m,k;
inline int read()
{
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0' && ch<='9')s=(s<<3)+(s<<1)+(ch^48),ch=getchar();
return s*w;
}
int main()
{
// freopen("in.txt","r",stdin);
n=read(),m=read(),k=read();
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)
a[i][j]=read();
for(int j=1;j<=m;++j)
{
int sum=0,cnt=0;
for(int i=1;i<=n;++i)
s[i]=s[i-1]+a[i][j];
for(int i=1;i<=n;++i)
{
int tmp=s[i+k-1]-s[i-1];
if(tmp>sum || (tmp==sum && s[i-1]<cnt))
sum=tmp,cnt=s[i-1];
}
ans+=sum,tot+=cnt;
}
printf("%d %d\n",ans,tot);
return 0;
}