单调队列1004 Codeforces Round #154 (Div. 2) 253D. Table with Letters - 2

来源:互联网 发布:域名证书是什么作用 编辑:程序博客网 时间:2024/05/26 09:57

题意:
给一个n*m的字母矩阵,问你有多少个子矩阵满足下面两个要求
1.矩阵四个角的字母都一样
2.矩阵内’a’的个数小于k
思路:
枚举矩阵的横边的行数,然后再枚举列数
因为每一列的状态得到的答案可以由之前列推出来
所以我们对每一列进行类似单调队列的推

#include<stdio.h>#include<string.h>#include<iostream>#include<algorithm>#include<math.h>#include<queue>#include<stack>#include<string>#include<vector>#include<map>#include<set>using namespace std;#define lowbit(x) (x&(-x))typedef long long LL;const int maxn = 405;const int inf=(1<<28)-1;char Table[maxn][maxn];int Num[maxn][maxn],Cnt[maxn];int main(){    freopen("input.txt", "r", stdin);    freopen("output.txt", "w", stdout);    int n,m,t;    scanf("%d%d%d",&n,&m,&t);    for(int i=1;i<=n;++i)        scanf("%s",Table[i]+1);    for(int i=1;i<=n;++i)    {        for(int j=1;j<=m;++j)        {            Num[i][j]=Num[i-1][j];            if(Table[i][j]=='a') Num[i][j]++;        }    }    LL Ans=0;    for(int i=1;i<n;++i)    {        for(int j=i+1;j<=n;++j)        {            memset(Cnt,0,sizeof(Cnt));            int Sum=0,l=1;            for(int k=1;k<=m;++k)            {                Sum+=Num[j][k]-Num[i-1][k];                //printf("%d %d %d %d ",i,j,k,Sum);                while(Sum>t&&l<=k)                {                    Sum-=Num[j][l]-Num[i-1][l];                    if(Table[i][l]==Table[j][l])                        Cnt[Table[i][l]-'a']--;                    l++;                }                if(Table[i][k]==Table[j][k])                {                    if(l<k)                        Ans+=Cnt[Table[i][k]-'a'];                    Cnt[Table[i][k]-'a']++;                }            }        }    }    printf("%lld\n",Ans);    return 0;}
0 0
原创粉丝点击