思路
- 题意:给一个m*n的矩阵,求其中有多少个子矩阵满足a的个数小于等于K,并且四个顶点字符相同
- 做法:先用前缀和,记下a的个数,在枚举一下上边和下边,之后用类似于双指针的做法,我们令左边的纵坐标为p,右边纵坐标为q,先移动右边,直到右边点a的字符个数大于K,每次移动右边如果右边的两个顶点相同就使该点字符的个数加一,如果右边不能移动了,就看下当前和左边顶点字符一样的右边字符有几个,ans加上这个值,之后左边往右移动,别忘记把该字符出现的次数减一。
#include<bits/stdc++.h>
const int maxn=1e5+10;
using namespace std;
int n,m,kk;
char a[500][500];
int sum[500][500];
map<char,int> mp;
int main()
{
scanf("%d%d%d",&n,&m,&kk);
for(int i=1; i<=n; i++)
scanf("%s",a[i]+1);
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++)
{
sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1];
if(a[i][j]=='a') sum[i][j]++;
}
long long ans=0;
for(int i=1; i<=n; i++)
{
for(int j=i+1; j<=n; j++)
{
int p=1;
mp.clear();
for(int k=1; k<=m; k++)
{
if(a[i][k]!=a[j][k]) continue;
while(p<=m&&sum[j][p]-sum[i-1][p]-sum[j][k-1]+sum[i-1][k-1]<=kk)
{
if(a[i][p]==a[j][p]) mp[a[i][p]]++;
p++;
}
mp[a[i][k]]--;
if(mp[a[i][k]]>0) ans+=mp[a[i][k]];
}
}
}
cout << ans;
return 0;
}