蓝桥杯,最后6天坚持就是胜利

目录

 

1.123

2.最优包含

3.混合牛奶


1.123

原题链接:123

题解思路:这题考察的是前缀和+二分,发现每一段的和是从一开始的一段连续区间,我们便可以用等差数列的求和公式进行求和,Sn=na1+n*(n-1)d/2,,于是我们可以预处理出来每段的前缀和当作每个元素,求的时候我们发现要找小于等于所求数的最大的元素的位置

 

#include<iostream>
#define int long long

using namespace std;

const int N = 1e7 + 10;
int n, m, flag;//flag 代表的是和的总数
int num[N];//存的是前缀和

void init() {
    for (int i = 1; i < N; i++) {
        int res = i * (i + 1) / 2;
        num[i] = res, num[i] += num[i - 1];
        flag++;
        if (res > 1e12) return;
    }
    return;
}
//等差数列求和公式 
int calc(int k) {
    if (k == 0) return 0;
    int l = 0, r = flag;
    while (l < r) {
        int mid = l + r + 1 >> 1;
        if (mid * (mid + 1) / 2 <= k) l = mid;
        else r = mid - 1;
    }
    int ans = num[l];//二分查找出小于等于所求数的最大的元素的位置
    int v = k - l * (l + 1) / 2;//所求位置的数
    ans += v * (v + 1) / 2;//求和
    return ans;
}

void solve() {
    cin >> n >> m;
    cout << calc(m) - calc(n - 1) << endl;
}

signed main() {
    init();
    int t;
    cin >> t;
    while (t--) {
        solve();
    }
}

2.最优包含

原题链接:最优包含

 解题思路:这题就是线性dp,类似于最短编辑距离问题,这里要注意f数组要初始化为无穷大便于求最小值,f[i][j]代表的是S串中前i个字符,包含有T串中前j个字符最少需要修改的字符个数,那么就有两种可能前i-1个都和t串的前j-1都相等,或者和t串的前j个都相等,

如果S[i]!=T[j],说明t串是比s串要短的,那么要么是让T[j]和S串的前i-1个的字符一样,要么就是让T【j】的前j-1项相等然后修改最后一位S[i]。

#include <bits/stdc++.h>
using namespace std;
const int N=1010;
char a[N],b[N];
int f[N][N];
int main()
{
   
    scanf("%s",a+1);
    scanf("%s",b+1);
    int n=strlen(a+1),m=strlen(b+1);
    memset(f,0x3f3f3f3f,sizeof f);
    f[0][0]=0;

    for(int i=1;i<=n;i++)
    {
    f[i][0]=0;
      for(int j=1;j<=m;j++)
       {
           if(a[i]==b[j]) 
				f[i][j]=min(f[i-1][j],f[i-1][j-1]);
            else 
				f[i][j]=min(f[i-1][j],f[i-1][j-1]+1);
         
           
       }
    } 
      cout<<f[n][m]<<endl;
      return 0;
    
}

3.混合牛奶

原题链接:

混合牛奶 

 题解思路:这题我用结构体来存储先按照单价排序,单价小的在前面; 单价一样的就把产量多的放前面,这样来保证费用是最小的

 

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

struct cow
{
    int a,b;//单价和总量
    
}c[5010];
bool cmp(cow a,cow b)
{
    if(a.a!=b.a)return a.a<b.a;//单价小的排在前面
    else return a.b>b.b;//若单价相同则总量大的排在前面
}
int main()
{
   int n,m,ans=0;
   cin>>n>>m;
   for(int i=1;i<=m;i++)
   {
       cin>>c[i].a>>c[i].b;
   }
   sort(c+1,c+1+m,cmp);
   int i=1;
   while(n)
   {
       if(c[i].b!=0)
       {
           c[i].b--;//产量减1
           ans+=c[i].a;//总花费加上单价
           n--;//所需求产量减一
       }
       else
       {
           i++;//当前农民的牛奶卖完了就换到下一个农民
       }
   }
   cout<<ans<<endl;
   return 0;
    
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值