蓝桥杯刷题笔记

1.凯撒加密

思路:定义string s,遍历s,对于是s【i】小于字符z,就往后面移三个字符,否则,s【i】为x,y,z的时候,分别改为字符a,b,c。最后输出字符串即可。

这里不知道为什么,一样的代码在蓝桥杯平台上一个过了5个数据,另外一个全部过了,有点莫名奇怪。

2.最大距离

思路:巧妙之处在于,定义maxx=-1,然后遍历数组a,求出max(abs(i-j)+abs(a[i]-a[j]),maxx),并且赋值给maxx。最后输出maxx即是我们求的答案

3.饮料换购

附上ac代码:

#include<bits/stdc++.h>

using namespace std;

int main(){
  ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);

  int n,ans=0;

  cin>>n;

  while(n>=3){
    n-=2;
    ans+=3;
  }

  ans+=n;

  cout<<ans<<endl;

  return 0;
}

思路:找规律,比如说,我现在有五个盖子,用掉三个,然后还剩三个(因为换购了的一个,加到剩余的里面去了)。每一次用掉三个,其实就是用现有的盖子数目减去二,然后ans+=2即可。还要考虑到,盖子数目小于3的情况,ans+=n即可。最后输出ans,即为我们总共喝到的饮料数目。

4.数位递增的数

附上ac代码

#include<bits/stdc++.h>

using namespace std;

int ans=0;

bool check(int t){
  char temp[8];

  sprintf(temp,"%d",t);
  string s(temp);

  for(int i=1;i<s.size();i++){
    if(s[i-1]>s[i]) return false;
  }

  return true;
}

int main(){
  ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);

  int n;
  cin>>n;

  for(int i=1;i<=n;i++){
    if(check(i)) ans++;
  }

  cout<<ans<<endl;

  return 0; 
}

思路:check()函数便是点睛之笔。开始拿到这题的时候,我想着定义一个数组,然后分别对数组的每个数去判断,如果满足条件,那么ans++,最后输出ans。但是编译器不通过,说是wrong answer。

这里的check()函数巧妙地将输入的数字用字符串来存放。因此在比较每一个数位的时候,就可以转化为字符数组来比较,十分方便!

5.最长递增

附上ac代码:

#include<bits/stdc++.h>

using namespace std;

const int N=1010;
int dp[N],a[N];
int n;

int main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    
    cin>>n;
    
    for(int i=1;i<=n;i++) cin>>a[i];
    
    for(int i=1;i<=n;i++) dp[i]=1;
    
    int res=1;
    for(int i=2;i<=n;i++){
        if(a[i]>a[i-1]){
            dp[i]=dp[i-1]+1;
            if(dp[i]>res) res=dp[i];
        }
    }
    
    cout<<res<<endl;
    
    return 0;
}

思路: 想着直接暴力去做,但是枚举下标的时候或多或少出现了error,于是乎找到此种解决方案--动态规划。

6.k倍区间

附上ac代码:

#include<bits/stdc++.h>

using namespace std;

const int N=1e5+10;
typedef long long LL;

LL s[N],cnt[N];   //s是前缀和数组,cnt是来存放余数的个数的数组
int n,k;

int main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	
	cin>>n>>k;
	
	for(int i=1;i<=n;i++){
		cin>>s[i];
		s[i]+=s[i-1];
	}
	
	LL res=0;  //注意开LL
	cnt[0]++;   //边界值要考虑,是因为模为0时区间本身也符合
	for(int i=1;i<=n;i++){
		res+=cnt[s[i]%k];
		cnt[s[i]%k]++;
	}
	
	cout<<res<<endl;
	
	return 0;
}

思路:y总的nb之处,就是将一段段区间,转化为前缀和存储起来。然后根据题意,区间之和要为k的倍数,即为区间之和模k为0。开一个cnt[]数组,来存放余数,这里要注意边界值,用res来接收余数,最后输出res即为我们所求的满足条件的区间个数!

7.空调

附上ac代码:

#include <iostream>

using namespace std;

const int N = 100010;

int n;
int b[N];

int main()
{
    scanf("%d", &n);
    for (int i = 1; i <= n; i ++ ) scanf("%d", &b[i]);
    for (int i = 1; i <= n; i ++ )
    {
        int x;
        scanf("%d", &x);
        b[i] -= x;
    }

    for (int i = n + 1; i; i -- ) b[i] -= b[i - 1];

    int res = 0;
    for (int i = 1; i <= n + 1; i ++ )
        if (b[i] > 0)
            res += b[i];

    printf("%d\n", res);

    return 0;
}

8.字符偏移(蓝桥最后一周周赛)

附上ac代码:

#include<bits/stdc++.h>

using namespace std;

const int N=2e5+10;
long long a[N],d[N];//a数组是将字符串转化为数字来存放,d数组为差分数组

int main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    
  int n,m;
  string s;
    
  cin>>n>>m>>s;
    
  for(int i=1;i<=n;i++){//初始化
    a[i]=s[i-1]-'a';
    d[i]=a[i]-a[i-1];
    }
    
    while(m--){
        int l,r,k;
        cin>>l>>r>>k;
        
        d[l]+=k;//对左区间来处理
        d[r+1]-=k;//对右区间来处理
    }
    
    for(int i=1;i<=n;i++) d[i]+=d[i-1];//求d数组的前缀和
    
    for (int i=1 ; i<=n ; i++) {
        cout << char('a' + d[i]%26 );
    }
    
    return 0;
}

思路:好好体会差分的应用!!!

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值