当前位置: 首页 > article >正文

蓝桥杯刷题冲刺 | 倒计时24天

作者:指针不指南吗
专栏:蓝桥杯倒计时冲刺

🐾马上就要蓝桥杯了,最后的这几天尤为重要,不可懈怠哦🐾

文章目录

  • 1.修剪灌木
  • 2.统计子矩阵

1.修剪灌木

  • 题目

    链接: 修剪灌木 - 蓝桥云课 (lanqiao.cn)

    找到一个蓝桥官网相比acwing刷题的优点:蓝桥官网可以看ac的占比

    爱丽丝要完成一项修剪灌木的工作。

    N 棵灌木整齐的从左到右排成一排。爱丽丝在每天傍晩会修剪一棵灌 木, 让灌木的高度变为 0 厘米。爱丽丝修剪灌木的顺序是从最左侧的灌木开始, 每天向右修剪一棵灌木。当修剪了最右侧的灌木后, 她会调转方向, 下一天开 始向左修剪灌木。直到修剪了最左的灌木后再次调转方向。然后如此循环往复。

    灌木每天从早上到傍晩会长高 1 厘米, 而其余时间不会长高。在第一天的 早晨, 所有灌木的高度都是 0 厘米。爱丽丝想知道每棵灌木最高长到多高。

    输入格式

    一个正整数 N, 含义如题面所述。

    输出格式

    输出 N 行, 每行一个整数, 第 i 行表示从左到右第 i 棵树最高能长到多高。

    样例输入

    3
    

    样例输出

    4
    2
    4
    
  • 第一次

    #include<bits/stdc++.h>
    using namespace std;
    
    const int N=1e4+10;
    int a[N],m[N];
    
    int main()
    {
        int n;
        scanf("%d",&n);
        
        int k=pow(n,2)+2;
        
        while(k>0)
        {
            for(int i=0;i<n;i++)
            {
                for(int j=0;j<n;j++)  //每天长1
                {
                    a[j]++;
                    m[j]=max(m[j],a[j]);
                } 
                a[i]=0;  //轮到的灌木,变0
            }
            for(int i=n-2;i>=1;i--)  //边界条件处理好
            {
                for(int j=0;j<n;j++)
                {
                    a[j]++;
                    m[j]=max(m[j],a[j]);
                }
                a[i]=0;
            }
            k-=2;
        }
        
        for(int i=0;i<n;i++)
            printf("%d\n",m[i]);
        
        return 0;
    }
    

    简单暴力,只能 ac 30%

    我感觉 每次 所有数组元素+1,可以优化成差分

  • 第二次

    #include<bits/stdc++.h>
    using namespace std;
    
    int main()
    {
        int n;
        cin>>n;
        
        for(int i=1;i<=n;i++)
        {
            cout<<max(n-i,i-1)*2<<endl; //找规律:当剪刀离灌木最远的时候,长的很高,然后返回马上要剪它的时候,最高,两倍高度;画图可知,到两个端点返回来的时候,最高
        }
        return 0;
    }
    

    在这里插入图片描述

  • 反思

    纯纯规律题,感觉错了

    发散性思维,在做蓝桥杯的时候,遇到这种 数 的题,先静下心来,找找规律

2.统计子矩阵

  • 题目

    链接: 4405. 统计子矩阵 - AcWing题库

    给定一个 N×M 的矩阵 A,请你统计有多少个子矩阵 (最小 1×1,最大 N×M) 满足子矩阵中所有数的和不超过给定的整数 K?

    输入格式

    第一行包含三个整数 N,M 和 K。

    之后 N 行每行包含 M 个整数,代表矩阵 A。

    输出格式

    一个整数代表答案。

    数据范围

    对于 30% 的数据,N,M≤20,
    对于 70%的数据,N,M≤100,
    对于 100% 的数据,1≤N,M≤500;0≤Aij≤1000;1≤K≤2.5× 1 0 8 10^8 108

    输入样例:

    3 4 10
    1 2 3 4
    5 6 7 8
    9 10 11 12
    

    输出样例:

    19
    

    样例解释

    满足条件的子矩阵一共有 19,包含:

    • 大小为 1×1 的有 10 个。
    • 大小为 1×2 的有 3 个。
    • 大小为 1×3 的有 2 个。
    • 大小为 1×4 的有 1 个。
    • 大小为 2×1 的有 3 个。
  • 第一次

    #include<bits/stdc++.h>
    using namespace std;
    
    const int N=510;
    int s[N][N];
    int n,m,k;
    
    int sum(int dx,int dy,int x,int y)
    {
        int res=0;
        res=s[x][y]-s[x-dx][y]-s[x][y-dy]+s[x-dx][y-dy];
        return res;
    }
    
    int main()
    {
        int cnt=0;
        
        scanf("%d%d%d",&n,&m,&k);
        
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
            {
                scanf("%d",&s[i][j]);
                s[i][j]+=s[i-1][j]+s[i][j-1]-s[i-1][j-1];  //前缀和
            }
        
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
            {
                for(int l=1;l<=n;l++)  // l,r 表示 每个小矩阵,右下角的元素
                    for(int r=1;r<=m;r++)
                    {
                        if(sum(i,j,l,r)<=k) cnt++;
                    }
                        
            }
        
        cout<<cnt;
        
        return 0;
    }
    

    答案错误,样例都过不了,目前还没有找出来 bug

  • 正确题解 ->前缀和+双指针

    思路

    前缀和 把数组 存起来

    用 四个指针 把 整个矩阵 分成 一小块一小块的

    左右使用 i,j 指针,上下 使用 u,d 指针

    在这里插入图片描述

    #include<bits/stdc++.h>
    using namespace std;
    
    const int N=510;
    int s[N][N];
    int n,m,k;
    
    int main()
    {
        scanf("%d%d%d",&n,&m,&k);
        
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
            {
                scanf("%d",&s[i][j]);
                s[i][j]+=s[i-1][j]+s[i][j-1]-s[i-1][j-1];
            }
        
          //i表示左边界,j表示右边界,u 表示上边界,d表示下边界
        
        long long ans=0;
        
        for(int i=1;i<=m;i++)
            for(int j=i;j<=m;j++)
            {
                for(int u=1,d=1;d<=n;d++)
                {
                    while(u<=d&&s[d][j]-s[u-1][j]-s[d][i-1]+s[u-1][i-1]>k) u++; //u++ 表示上边界下移,区间变小,递减
                    if(u<=d) ans+=d-u+1;  //表示这段区间的矩阵,满足条件
                }
            }
                
        cout<<ans;
        
        return 0;
    }
    
  • 反思

    及时复习前面的知识,忘光了

    遇到矩阵和,优先想到前缀和,然后,有区间的移动问题,使用双指针

    定义变量之前,先想清楚,它的数据类型和范围

Alt


http://www.kler.cn/a/502.html

相关文章:

  • 【vue2父组件调用子组件方法之slot的使用】
  • windos挂载目录到linux
  • 散斑/横向剪切/迈克尔逊/干涉条纹仿真技术分析
  • Go singleflight库源码分析
  • 我的创作纪念日(五年)
  • 学习threejs,THREE.CircleGeometry 二维平面圆形几何体
  • 【pygame游戏】Python实现蔡徐坤大战篮球游戏【附源码】
  • 17.电话号码的字母组合(深度递归遍历解决经典老题)
  • Python的30个编程技巧
  • 软测面试了一个00后,绝对能称为是内卷届的天花板
  • 数据结构One——绪论
  • ChatGPT是如何训练得到的?通俗讲解
  • 程序员必会技能—— 使用日志
  • 【IoT】嵌入式驱动开发:IIC子系统
  • Qt浏览器开发:关于QCef以及qcefview开发原理
  • 做技术,最忌讳东张西望
  • ChatGPT解答:python大批量读写ini文件时,性能很低,有什么解决方法吗,给出具体的思路和实例
  • Spring学习——MyBatisPlus入门
  • 极智AI | GPT4来了,ChatGPT又该升级了
  • JS学习第11天——函数进阶(this指向、严格模式、高阶函数、闭包、递归)
  • 一个nginx的小项目,不写代码,实现在局域网内访问其他电脑的网页
  • 裸辞3个月,面试了25家公司,终于找到心仪的工作了
  • C#基础之面向对象编程(二)
  • MySQL:JDBC
  • 快速测试两台服务器间的网速(ChatGPT回复)
  • 2022年全国职业院校技能大赛(中职组)网络安全竞赛试题——MYSQL安全测试解析(详细)