「土」秘法地震 题解

「土」秘法地震

https://ac.nowcoder.com/acm/problem/53676

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

解法一.暴力

按照题目说的模拟去做,复杂度,期望得分: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;
}
全部评论

相关推荐

HR_丸山彩同学:你的项目描述里,系统设计讲了很多:MemCube是什么、三级存储架构怎么设计、四种遗忘策略分别是什么。这些面试的时候讲没问题,但简历上不需要这么细。 简历要突出的是影响力,不是实现细节。面试官看简历的时候想知道的是「这个项目有多大价值」,不是「这个项目具体怎么实现的」。实现细节是面试时候聊的 怎么改:技术细节可以精简为一句「采用三级存储架构+四种遗忘策略」,把省出来的篇幅用来写影响力。比如:项目有没有开源?有没有写成技术博客?有没有被别人使用过? 校园经历没有任何信息量,任何人都可以写这句话,写了等于没写。更关键的是,你投的是技术岗,校园活动经历本来就不是加分项。如果非要写,必须写出具体的数字和成果。如果你没有这些数字,那就老老实实删掉 「端到端耗时缩减30-40%」要给出确切数字和绝对值。从1000ms降到600ms是降了40%,从100ms降到60ms也是降了40%,但这两个含义完全不一样。其他也是,涉及到数据,准备好证据,口径统一,面试会问 「熟练」「熟悉」「了解」混在一起用,读起来很乱。而且「了解前端需求」最好改成「具备前后端协作经验」
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务