每日算法题-蓝桥经典题

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

在这个瞬息万变的时代,科技发展日新月异,编程作为一项基础技能,已逐渐成为人们不可或缺的一部分。参加算法练习赛有很多好处,例如提高编程技能、锻炼思维能力、增强自信心等等。

打算法竞赛,要多进行练习,去洛谷,牛客网,蓝桥杯等等网站上多参加练习赛和周赛,实力强可以去Codeforces上练习。话不多说,开始今日份习题讲解。

叮!你有一份习题请查收!


一、前缀和习题

数组段数

1.题目链接

C-数组段数_牛客小白月赛86(重现赛) (nowcoder.com)

2.题目描述

3.题目讲解

首先,拿到本题,我们先理解题意:

小红对小灰灰提出了m个询问,第i个询问给出两个参数L, R,代表小红截取了原数组的的一部分。对于每个询问,小灰灰想知道小红截取出的数组有多少段。其段数被定义为最小的 k 使得将数组划分成连续的 k 段后,每个元素都属于某一段,且每段数组中的元素种类应该全部相同。

简单来说,就是在给出一段数组在查询有多少段,相邻的元素如果相同则为一段,那不是好办嘛,一个for循环,检查a[i]!=a[i+1]时候,计数cnt加一就好啦,但事情有我们想的那么简单吗?

上代码!

#include<bits/stdc++.h>
using namespace std;

const int N=2e5+10;
int a[N];

int main(){
  int n,m;
  scanf("%d%d",&n,&m);
  for(int i=1;i<=n;i++) scanf("%d",&a[i]);
  while(m--){
    int l,r,cnt=0;
    scanf("%d%d",&l,&r);
    for(int i=l;i<r;i++){
      if(a[i]!=a[i+1]) cnt++;
    }
    printf("%d\n",cnt+1);
  }
  return 0;
}

样例加入,没毛病,提交!不出意外,超时了!!!

那我们怎么思考呢?在区间进行操作,这不是我前几天蓝桥杯真题所运用的前缀和思想!(详见每日算法题-蓝桥杯真题-CSDN博客)和(基本算法-前缀和 模板+习题-CSDN博客

那在本题怎么使用呢?

发现相同时不累加,不相同累加,那么假定S代表前缀和数组,查询数组区间有几段,不就是就区间的前缀和嘛!

欧克了,那怎么构造前缀和公式呢?重点在这一句:相同时不累加,不相同累加,则可得到:

S[i]=S[i-1]+(A[i]!=A[i-1])

那么区间内前缀和则为:s[r]-s[l-1],还有一个小点我们要考虑到,假设区间外的数和查询区间的第一个重复那么要多加一个1,因此求区间前缀和为:

s[r]-s[l-1]+(a[l]==a[l-1])

最后,就是上代码环节,虽然有人就看这个(狗头保护)

4.完整代码

#include<bits/stdc++.h>
using namespace std;

const int N=2e5+10;
long long a[N],s[N];

int main(){
  int n,m;
  scanf("%d%d",&n,&m);
  for(int i=1;i<=n;i++) {
      scanf("%lld",&a[i]);
      s[i]=s[i-1]+(a[i]!=a[i-1]);
  }
      
  while(m--){
    int l,r,cnt=0;
    scanf("%d%d",&l,&r);
    printf("%lld\n",s[r]-s[l-1]+(a[l]==a[l-1]));
  }
  return 0;
}

二、模拟习题

 乘飞机【算法赛】

1.题目链接

4.乘飞机【算法赛】 - 蓝桥云课 (lanqiao.cn)

2.题目描述

3.题目讲解

本题题意:在给定区间中是否存在两个数相差小于或者365,那按照题意模拟即可。

我用的是暴力法,根据题意,两层for循环,加判断z=abs(a[i]-a[j]),判断条件z<=365

即可(本题测试数据比较水,暴力即可通过,其实很莫名其妙,才开始不通过,然后有修改了一点点过了,哈哈哈)

还有一种方法是,当区间之差大于100,一定是YES,小于100时暴力,这样如果数据量大,不会超时,但为什么大于100,就一定是YES,鸽笼原理,36500/100=365,在大于100,一定有插值小于或者等于365(因为已经全部枚举过了,举一个例子更好理解,任意 367  个人中至少有 2 人生日(出生的月和日)相同。)

4.完整代码

(1)暴力
#include <iostream>
using namespace std;
const int N=1e5+10;
int a[N];

int main()
{
  int n,m,cnt=0;
  cin>>n>>m;
  for(int i=1;i<=n;i++) scanf("%d",&a[i]);
  while(m--){
    int x,y,cnt=0;
    scanf("%d%d",&x,&y);
    for(int i=x;i<=y-1;i++){
      for(int j=i+1;j<=y;j++){
      int z=abs(a[i]-a[j]);
      if(z<=365) {
        cnt=1;
        printf("YES\n");
        break; 
        }     
      }
      if(cnt) break;
    }
    if(!cnt) printf("NO\n");
  }
  return 0;
}
(2) 鸽笼原理
#include <iostream>
using namespace std;
const int N=1e5+10;
int a[N];

int main()
{
  int n,m;
  cin>>n>>m;
  for(int i=1;i<=n;i++) scanf("%d",&a[i]);
  while(m--){
    int x,y,cnt=0;
    scanf("%d%d",&x,&y);
    if(y-x>100) cout<<"YES"<<endl;
    else{
    for(int i=x;i<=y-1;i++){
      for(int j=i+1;j<=y;j++){
      int z=abs(a[j]-a[i]);
      if(z<=365) cnt=1;

      if(cnt==1) break;
      else continue;        
      }
    }
    if(cnt==1) cout<<"YES"<<endl;
    else cout<<"NO"<<endl;      
    }

  }
  return 0;
}

总结

结束了!!!

看完了?可以给作者一个赞和收藏,嘿嘿,要不顺手点个关注?希望能和友友们交流,以及欢迎友友们评论!

这是这周参加了两场算法比赛,分别是蓝桥小白,和牛客网小白比赛,蓝桥ac4道,牛客ac3道,下周进行搜索专题学习,牛客网第四道是连通块的题,好久之前看的,已经不会敲了,下周继续努力!!!

本周博客总结:

基本算法-差分 模板+习题-CSDN博客

每日算法题-蓝桥杯真题-CSDN博客

基本算法-高精度加法 模板+习题-CSDN博客

基本算法-前缀和 模板+习题-CSDN博客

感兴趣的小伙伴可以去看一看哦。

 

  • 28
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不想敲代码的小趴菜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值