本来打算只写一种解法的,不过感觉太水了,就多写点吧

解法一.暴力

按照题目说的模拟去做,复杂度,期望得分:70-100(数据有点弱啊qwq)

解法二.带优化的暴力

我们设a[i][j]表示i,j点的正下面中,包含i,j的k格格子中是否至少存在一个1。

这个直接暴力统计就好了,当然,你要把存在改成有几个的话,就可以直接计算了

然后,我们枚举每个k*k矩形的左上角,设为(x,y),那么,我们只要中有一个1,那么这个k*k的矩形中就会有一个1。直接暴力统计或者跟上面的方法一样计算也行。

复杂度:,期望得分:100

解法三.二维前缀和

我们直接预处理出二维前缀和(每个点到1,1所构成的矩阵中,元素之和)

那么, 我们还是枚举一个左上角,然后直接根据二维前缀和的公式,就可以O(1)算出以(x,y)为左上角的一个k*k的矩形的所有元素之和,如果和大于0,则说明其中必然有至少一个1,那么答案加1即可

复杂度:,期望得分:100

代码:

[可过版甚至比我正解还快]

```#include<bits/stdc++.h>
using namespace std;
const int N=1001;
bool s[N][N],q[N][N];
int main(){
    int n,m,k;
    scanf("%d%d%d",&n,&m,&k);
    for(int i=1;i<=n;++i){
        for(int j=1;j<=m;++j){
            scanf("%1d",&s[i][j]);//输入小技巧,即只输入一个数字
        }
    }
    int ans=0;
    for(int i=1;i<=n;++i){
        for(int j=1;j<=m;++j){
            if(s[i][j]){
                for(int t=max(1,i-k+1);t<=i;++t){
                    for(int p=max(1,j-k+1);p<=j;++p){
                        q[t][p]=1;
                    }
                }
            }
        }
    }
    for(int i=1;i<=n-k+1;++i){
        for(int j=1;j<=m-k+1;++j){
            ans+=q[i][j];
        }
    }
    printf("%d",ans);
    return 0;
}

#include<bits/stdc++.h>
using namespace std;
const int N=1001;
bool s[N][N];
bool a[N][N],q[N][N];
int main(){
    int n,m,k;
    scanf("%d%d%d",&n,&m,&k);
    for(int i=1;i<=n;++i){
        for(int j=1;j<=m;++j){
            scanf("%1d",&s[i][j]);
        }
    }
    for(int i=1;i<=n;++i){
        for(int j=1;j<=m;++j){
            if(s[i][j]){
                for(int t=i;t>=max(1,i-k+1);--t){
                    a[t][j]=1;
                }
            }
        }
    }
    for(int i=1;i<=n;++i){
        for(int j=1;j<=m;++j){
            for(int t=j;t<=min(m,j+k-1);++t){
                q[i][j]|=a[i][t];
            }
        }
    }
    int ans=0;
    for(int i=1;i<=n-k+1;++i){
        for(int j=1;j<=m-k+1;++j){
            ans+=q[i][j];
        }
    }
    printf("%d",ans);
    return 0;
}

#include<bits/stdc++.h>
using namespace std;
const int N=1001;
bool s[N][N];int a[N][N],b[N][N];
int main(){
    int n,m,k;
    scanf("%d%d%d",&n,&m,&k);
    for(int i=1;i<=n;++i){
        for(int j=1;j<=m;++j){
            scanf("%1d",&s[i][j]);
        }
    }
    for(int i=1;i<=n;++i){
        for(int j=1;j<=k;++j){
            a[i][1]+=s[i][j];
        }
        for(int j=2;j<=m-k+1;++j){
            a[i][j]=a[i][j-1]-s[i][j-1]+s[i][j+k-1];
        }
    }
    for(int i=1;i<=m;++i){
        for(int j=1;j<=k;++j){
            b[1][i]+=a[j][i];
        }
        for(int j=2;j<=n-k+1;++j){
            b[j][i]=b[j-1][i]-a[j-1][i]+a[j+k-1][i];
        }
    }
    int ans=0;
    for(int i=1;i<=n-k+1;++i){
        for(int j=0;j<=m-k+1;++j){
            ans+=(b[i][j]>0);
        }
    }
    printf("%d",ans);
    return 0;
}

#include<bits/stdc++.h>
using namespace std;
const int N=1001;
int s[N][N];
int main(){
    int n,m,k;
    scanf("%d%d%d",&n,&m,&k);
    for(int i=1;i<=n;++i){
        for(int j=1;j<=m;++j){
            scanf("%1d",&s[i][j]);
        }
    }
    for(int i=2;i<=n;++i){
        s[i][1]+=s[i-1][1];
    }
    for(int i=2;i<=m;++i){
        s[1][i]+=s[1][i-1];
    }
    for(int i=2;i<=n;++i){
        for(int j=2;j<=m;++j){
            s[i][j]+=(s[i-1][j]+s[i][j-1]-s[i-1][j-1]);
        }
    }
    int ans=0;
    for(int i=1;i<=n-k+1;++i){
        for(int j=1;j<=m-k+1;++j){
            int a=i,b=j,c=i+k-1,d=j+k-1;
            ans+=((s[c][d]-s[a-1][d]-s[c][b-1]+s[a-1][b-1])>0);
        }
    }
    printf("%d",ans);
    return 0;
}