蓝桥杯python小白逆袭之路

 

import os

import sys

# 请在此输入您的代码

n, B=map(int,input().split())

a=list(map(int,input().split()))

sum=0 #用于判断奇数与偶数的个数

cnt=[]#存放可切片的位置

for i in range(n):

  if a[i]&1:

      sum=sum+1

  else :

      sum=sum-1

  if sum==0 and i+1<n: #当奇偶数相同且满足零花钱个数的要求时

    #可切片 并将可切片的位置de花费代价进行存放

    cnt.append(abs(a[i+1]-a[i]))

cut=0 #进行操作的次数

cnt.sort()

for c in cnt:

    if B>=c:

      B-=c

      cut+=1

    else:

        break

print(cut)

小蓝的零花钱

解题思路

首先,我们可以将题目中的序列看成偶数和奇数的交错序列。我们可以用变量 sumsum 记录当前序列中偶数和奇数的个数之差,当 sumsum 等于 00 时,说明当前位置可以进行一次操作,因为此时序列可以被分成两段,且每个段中奇数和偶数的个数相等。

对于每次操作,我们需要计算其代价。我们可以将两个相邻操作之间的元素放在一起,这样得到的新序列中奇数和偶数的个数之差依然为 00。那么我们可以计算相邻两次操作之间的元素差的绝对值,从中选取代价最小的一次操作执行。

接下来,我们可以将每个可操作的位置看成一个区间。假设共有 mm 个可操作的位置,对这 mm 个区间按照代价从小到大排序,然后从小到大枚举每个区间,如果当前的预算 BB 足够进行这个区间的操作,那么就执行这个操作,并将答案 ansans 加 11,同时减去操作的代价 cnt_icnti​。如果 BB 不足以进行这个区间的操作,那么就结束枚举,输出答案 ansans。

时间复杂度为 O(n\log n)O(nlogn),其中 \log nlogn 为排序的时间复杂度。

AC_Code

  • C++
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int n , a[N] , cnt[N];
signed main()
{
    int n , B;
    cin >> n >> B;
    for(int i = 1 ; i <= n ; i ++) cin >> a[i];
    int sum = 0 , now = 0;
    for(int i = 1 ; i <= n ; i ++){
        if(a[i] & 1) sum ++ ;
        else sum -- ;
        if(sum == 0 && i + 1 <= n) 
        cnt[++ now] = abs(a[i + 1] - a[i]);
    }
    sort(cnt + 1 , cnt + 1 + now);
    int ans = 0;
    for(int i = 1 ; i <= now ; i ++){
        if(B >= cnt[i]) B -= cnt[i] , ans ++ ;
        else break ;
    }
    cout << ans << '\n';
    return 0;
}

  • Java
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        int n = scan.nextInt();
        int B = scan.nextInt();
        int[] a = new int[n + 1];
        for (int i = 1; i <= n; i++) a[i] = scan.nextInt();

        int sum = 0, now = 0;
        int[] cnt = new int[n + 1];
        for (int i = 1; i <= n; i++) {
            if (a[i] % 2 == 1) sum++;
            else sum--;
            if (sum == 0 && i + 1 <= n) cnt[++now] = Math.abs(a[i + 1] - a[i]);
        }
        Arrays.sort(cnt, 1, now + 1);

        int ans = 0;
        for (int i = 1; i <= now; i++) {
            if (B >= cnt[i]) {
                B -= cnt[i];
                ans++;
            } else break;
        }

        System.out.println(ans);
    }
}

  • Python
n, B = map(int, input().split())
a = list(map(int, input().split()))

sum = 0
cnt = []  # 记录每个区间的代价
for i in range(n):
    if a[i] & 1:
        sum += 1
    else:
        sum -= 1
    if sum == 0 and i + 1 < n:
        cnt.append(abs(a[i + 1] - a[i]))

cnt.sort()
ans = 0
for c in cnt:
    if B >= c:
        B -= c
        ans += 1
    else:
        break

print(ans)
  • 8
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值