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

<蓝桥杯软件赛>零基础备赛20周--第11周--贪心

报名明年4月蓝桥杯软件赛的同学们,如果你是大一零基础,目前懵懂中,不知该怎么办,可以看看本博客系列:备赛20周合集
20周的完整安排请点击:20周计划
每周发1个博客,共20周。
在QQ群上答疑:

在这里插入图片描述

文章目录

  • 1. 贪心思想
  • 2. 经典贪心问题
    • 2.1 部分背包问题
    • 2.2 不相交区间问题(或称为区间调度问题、活动安排问题)
    • 2.3 区间合并问题
    • 2.4 区间覆盖问题
  • 3. 例题
    • 3.1 买二赠一
    • 3.2 购物
    • 3.3 管道
  • 4. 习题

第9周:贪心

备赛20周活动已经到第11周了,快到期末考试阶段了。最近做题的人很少了。

1. 贪心思想

  贪心是蓝桥杯省赛的必考知识点,每年都有。
  贪心(Greedy)是容易理解的算法思想:把整个问题分解成多个步骤,在每个步骤,都选取当前步骤的最优方案,直到所有步骤结束;在每一步,都不考虑对后续步骤的影响,在后续步骤中也不能回头改变前面的选择

作者拟过2句赠言:“贪心说,我从不后悔我走过的路”“贪心说,其实我有一点后悔,但是我回不了头”
大多数读者选前一句。

  贪心策略在生活中经常用到。例如下象棋时,初级水平的棋手只会“走一步看一步”,就是贪心法。而水平高的棋手能“走一步看三步”,轻松击败初级棋手。
  贪心这种“只顾当下,不管未来”的解题策略,让人疑惑:在完成所有局部最优操作后,得到的解不一定是全局最优,那么热如何判断能不能用贪心呢?
  有时很容易判断:一步一步在局部选择最优,最后结束时能达到全局最优。例如吃自助餐,怎么吃才能“吃回票价”?它的数学模型是一类背包问题,称为“部分背包问题”:有一个容量为C的背包,有m种物品,第i种物品有wi千克,单价为vi,且每种物品是可以分割的,例如大米、面粉等;问如何选择物品,使得装满背包时,总价值最大。显然可以用贪心法,只要在当前物品中选最贵的放进背包就行了:先选最贵的物品A,A放完之后,再选剩下最贵的物品B,…,直到背包放满。
  有时看起来能用贪心,但实际上贪心的结果不是最优解。例如最少硬币支付问题:有多种面值的硬币,数量不限;需要支付M元,问怎么支付,才能使硬币数量最少?
  最少硬币支付问题是否能用贪心求最优解,和硬币的面值有关。
  任意面值的最少硬币支付问题,正解是动态规划。参考《算法竞赛入门到进阶》清华大学出版社,罗勇军著,“7.1.1 硬币问题”给出了各种硬币问题的动态规划解法。
  如果硬币面值为1元、2元、5元,用贪心是对的。贪心策略是当前选择可用的最大面值的硬币。例如支付M=18元,第一步选面值最大的5元硬币,用掉3个硬币,还剩3元;第二步选面值第二大的2元硬币,用掉1个硬币,还剩1元;最后选面值最小的1元硬币,用掉1个;共用5个硬币。在这个解决方案中,硬币数量总数是最少的,贪心法的结果是全局最优的。
  但是如果是其他面值的硬币,贪心法就不一定能得到全局最优解。例如,硬币的面值很奇怪,分别是1、2、4、5、6元。支付M = 9元,如果用贪心法,每次选择当前最大面值硬币,那么答案是6 + 2 + 1,需要3个硬币,而最优解是5 + 4,只需要2个硬币。
  判断一个题目是不是能用贪心,需要满足以下特征:
  1)最优子结构性质。当一个问题的最优解包含其子问题的最优解时,称此问题具有最优子结构性质,也称此问题满足最优性原理。
  2)贪心选择性质。问题的整体最优解可以通过一系列局部最优的选择来得到。也就是说,通过一步步局部最优能最终能得到全局最优。
  最后讨论贪心法的效率,贪心法的计算量是多少?贪心法由于每一步都在局部做计算,且只选取当前最优的步骤做计算,不管其他可能的计算方案,所以计算量很小。在很多情况下,贪心法可以说是计算复杂度最低的算法了。与此相对,暴力法一般是计算复杂度最差的,因为暴力法计算了全局的所有可能的方案。
  由于贪心的效率高,所以如果一个问题确定可用贪心法能得到最优解,那么应该使用贪心。如果用其他算法,大概率会超时。
  在算法竞赛中,贪心法几乎是必考点,有的题考验思维能力,有的题结合了贪心和其他算法。虽然贪心策略很容易理解,但贪心题可能很难。
  贪心也是蓝桥杯大赛的常见题型。不论是省赛还是国赛,贪心出现的概率都非常大。
  虽然贪心法不一定能得到最优解,但是它解题步骤简单、编程容易、计算量小,得到的解“虽然不是最好,但是还不错!”。像蓝桥杯这种赛制,一道题有多个测试点,用贪心也许能通过10%~30%,若别无他法,值得一试。

2. 经典贪心问题

2.1 部分背包问题

  前文介绍了用贪心求解部分背包问题,下面是例题。
例题:部分背包问题
  下面直接给出代码。
C++代码

#include<bits/stdc++.h>
using namespace std;
struct gold{ double w,v,p; }a[105];  //w,v,p: 重量,价值,单价
bool cmp(gold a, gold b){ return a.p > b.p;  } //单价从大到小排序
int main(){int n,c; cin>>n>>c;for(int i=0;i<n;i++){cin >> a[i].w >> a[i].v;a[i].p = a[i].v/a[i].w;  //计算单价}sort(a,a+n,cmp);         //按单价排序double sum=0.0;           //最大价值for(int i=0;i<n;i++){if(c >= a[i].w){     //第i种金币比背包容量小c -= a[i].w;     //背包还有余量sum += a[i].v;   //累计价值}else{               //第i种金币很多,直接放满背包sum += c*a[i].p;break;}}printf("%.2f",sum);//保留小数点后两位输出return 0;
}

Java代码

import java.util.*;
class Main {static class Gold { double w, v, p; }public static void main(String[] args) {Scanner scanner = new Scanner(System.in);int n = scanner.nextInt();int c = scanner.nextInt();Gold[] a = new Gold[n];for (int i = 0; i < n; i++) {a[i] = new Gold();a[i].w = scanner.nextDouble();a[i].v = scanner.nextDouble();a[i].p = a[i].v/a[i].w;}Arrays.sort(a, new Comparator<Gold>() {public int compare(Gold a, Gold b) {return Double.compare(b.p, a.p);}});double sum = 0.0;for (int i = 0; i < n; i++) {if (c >= a[i].w) {c -= a[i].w;sum += a[i].v;} else {sum += c * a[i].p;break;}}System.out.printf("%.2f", sum);}
}

Python代码

n, c = map(int, input().split())
a = []
for i in range(n):w, v = map(int, input().split())p = v / wa.append((w, v, p))
a.sort(key=lambda x: x[2], reverse=True)
sum = 0.0
for i in range(n):if c >= a[i][0]:c -= a[i][0]sum += a[i][1]else:sum += c * a[i][2]break
print("%.2f" %sum)

2.2 不相交区间问题(或称为区间调度问题、活动安排问题)

  给定一些区间(活动),每个区间有左端点和右端点(开始时间和终止时间),要求找到最多的不相交区间(活动)。
  以下按“活动安排问题”来解释。
  这个问题的目的是求最多活动数量,所以那种持续时间长的活动不受欢迎,受欢迎的是尽快结束的、持续时间短的活动。
  考虑以下3种贪心策略:
  1)按最早开始时间贪心:先选最早开始的活动a,当a结束后,再选下一个最早开始的活动。这种策略不好,因为它没有考虑活动的持续时间。假如a一直不结束,那么其他活动就不能开始。
  2)最早结束时间:先选最早结束的活动a,a结束后,再选下一个最早结束的活动。这种策略是合理的。越早结束的活动,越能腾出后续时间容纳更多的活动。
  3)用时最少:先选时间最短的活动a,再选不冲突的下一个最短活动。这个策略似乎也可行,但是很容易找到反例,证明这个策略不正确。
  下图的例子,
  用“策略1)最早开始时间”,选3;
  用“策略2)最早结束时间”,选1、2、5、6;
  用“策略3)用时最少”,选4、1、2。
  策略2)的结果是最好的。
在这里插入图片描述
  总结活动安排问题的贪心策略:先按活动的结束时间(区间右端点)排序,然后每次选结束最早的活动,并保证选择的活动不重叠。

例题:线段覆盖

C++代码

#include<bits/stdc++.h>
using namespace std;
struct data{int L, R;                             //开始时间、结束时间
}a[1000005];
bool cmp(data x,data y){return x.R<y.R; } //按照结束时间排序
int main(){int n;   cin >> n;for(int i=0;i<n;i++)   cin>>a[i].L>>a[i].R;sort(a,a+n,cmp);int ans = 0;int lastend = -1;for(int i=0;i<n;i++)if(a[i].L>=lastend) {ans++;lastend = a[i].R;}cout<<ans;return 0;
}

Java代码

import java.util.*;
class Main {static class Data { int L, R; }        // 开始时间、结束时间public static void main(String[] args) {Scanner scanner = new Scanner(System.in);int n = scanner.nextInt();Data[] a = new Data[n];for (int i = 0; i < n; i++) {a[i] = new Data();a[i].L = scanner.nextInt();a[i].R = scanner.nextInt();}Arrays.sort(a, new Comparator<Data>() {public int compare(Data x, Data y) {return x.R - y.R;}});int ans = 0;int lastend = -1;for (int i = 0; i < n; i++) if (a[i].L >= lastend) {ans++;lastend = a[i].R;}System.out.println(ans);}
}

python代码

n = int(input())
a = []
for _ in range(n):L, R = map(int, input().split())a.append((L, R))
a.sort(key=lambda x: x[1])      # 按照结束时间排序。请与下一个例题比较
ans = 0
lastend = -1
for i in range(n):if a[i][0] >= lastend:ans += 1lastend = a[i][1]
print(ans)

2.3 区间合并问题

  区间合并问题:给定若干个区间,合并所有重叠的区间,并返回不重叠的区间个数。
  以下图为例,1、2、3、5合并,4、6合并,新区间是1’、4’。
在这里插入图片描述
  贪心策略:按区间左端点排序,然后逐一枚举每个区间,合并相交的区间。
  定义不重叠的区间个数(答案)为ans。设当前正在合并的区间的最右端点为end,枚举到第i个区间[Li, Ri]时:
  若Li≤end,说明与第i区间相交,需要合并,ans不变,更新end = max(end, Ri)。
  若Li > end,说明与第i区间不相交,ans加1,更新 end = max(end, Ri)。
  请读者用上图的例子,模拟合并过程。

2.4 区间覆盖问题

  区间覆盖问题:给定一个目标大区间,和一些小区间,问最少选择多少小区间,可以覆盖大区间。
  贪心策略:尽量找出右端点更远的小区间。
  操作步骤:先对小区间的左端点排序,然后依次枚举每个小区间,在所有能覆盖当前目标区间右端点的区间之中,选择右端点最大的区间。
  下图中,求最少用几个小区间能覆盖整个区间。先按左端点排序。设当前覆盖到了位置R,选择的小区间数量为cnt。
在这里插入图片描述
  从区间1开始,R的值是区间1的右端点A,R=A。cnt=1。
  找到能覆盖R=A的区间2、3,在区间2、3中选右端点更远的3,更新R为区间3的右端点B,R=B。cnt=2。
  区间4不能覆盖R=B,跳过。
  找到能覆盖R=B区间5,更新R=C。cnt=3。结束。

例题:区间覆盖

C++代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
struct data{ll L,R;
} a[100005];
bool cmp(data x,data y){return x.L < y.L; } //按左端点排序
int main(){int n; cin>>n;for (int i=0;i<n;i++) cin>>a[i].L>>a[i].R;sort(a,a+n,cmp);ll lastend=-1,ans=0;for (int i=0;i<n;i++)if (a[i].R >= lastend){ans += a[i].R - max(lastend,a[i].L)+1;lastend = a[i].R+1;}cout<<ans;return 0;
}

Java代码

import java.util.*;class Main {static class Data {long L, R;}public static void main(String[] args) {Scanner scanner = new Scanner(System.in);int n = scanner.nextInt();Data[] a = new Data[n];for (int i = 0; i < n; i++) {a[i] = new Data();a[i].L = scanner.nextLong();a[i].R = scanner.nextLong();}Arrays.sort(a, new Comparator<Data>() {public int compare(Data x, Data y) {return Long.compare(x.L, y.L);}});long lastend = -1;long ans = 0;for (int i = 0; i < n; i++) if (a[i].R >= lastend) {ans += a[i].R - Math.max(lastend, a[i].L) + 1;lastend = a[i].R + 1;}System.out.println(ans);}
}

python代码

class Data:          def __init__(self, L, R):self.L = Lself.R = R
def cmp(x, y):   return x.L < y.L    #这里用函数比较。请对比上一题代码n = int(input())
a = []
for _ in range(n):L, R = map(int, input().split())a.append(Data(L, R))
a.sort(key=lambda x: x.L)
lastend = -1
ans = 0
for i in range(n):if a[i].R >= lastend:ans += a[i].R - max(lastend, a[i].L) + 1lastend = a[i].R + 1
print(ans)

3. 例题

3.1 买二赠一

2023年蓝桥杯省赛 Java B组 G题 20分
看起来这20分不难拿哦

链接:买二赠一
  最贵的商品显然不能免单,买了2个不能免单的最贵商品后,获得一个免单机会,那么这个免单机会给谁呢?就给能免单的最贵的那个商品。这个贪心思路显然是对的。
  以样例为例,先排序得{8 7 5 4 2 1 1}。先购买最贵的8、7,然后可以免单的最贵的是2。再购买剩下的最贵的5、4,免单1。最后单独买1。总价是25。
  C++代码。需要查找价格为P/2的商品, 由于价格已经排序,可以用二分法加快查找的时间。这里直接用二分法的库函数lower_bound()查找。

#include<bits/stdc++.h>
using namespace std;
const int N = 5e5 + 10;
int a[N];
bool vis[N];  //vis[i]=1表示已经免单了
int main(){int n; scanf("%d", &n);for(int i = 0; i < n; i++)   scanf("%d", &a[i]);sort(a, a + n);long long ans = 0;int cnt = 0;int last = -1;   //购买的2件中的便宜的那件last_id = n-1;   //能免单的位置for(int i = n-1; i >= 0; i--){if(!vis[i])cnt++, ans += a[i], last = a[i];  //last是买的第2件if(cnt == 2){  //买了2个cnt = 0;int x = lower_bound(a , a  + last_id, last / 2) - a;  //找能免单的商品a[x]if(x > last_id || a[x] > last / 2)  x--;   //向下取整if(x>=0){vis[x] = 1;   //x免单了last_id = x-1; //后面能免单的区间范围是[0,last_id]}}}cout<<ans<<endl;return 0;
}

Java代码。Java没有自带的二分函数,只好自己写一个lowerBound()。

import java.util.Arrays;
import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);int n = scanner.nextInt();int[] a = new int[n];for (int i = 0; i < n; i++)       a[i] = scanner.nextInt();Arrays.sort(a);long ans = 0;int cnt = 0;int last = -1;int last_id = n - 1;boolean[] vis = new boolean[n];for (int i = n - 1; i >= 0; i--) {if (!vis[i]) {cnt++;ans += a[i];last = a[i];}if (cnt == 2) {cnt = 0;int x = lowerBound(a, 0, last_id, last / 2);if (x > last_id || a[x] > last / 2) x--;if (x >= 0) {vis[x] = true;last_id = x - 1;}}}System.out.println(ans);}private static int lowerBound(int[] a, int L, int R, int target) {while (L < R) {int mid = L + (R - L) / 2;if (a[mid] >= target)  R = mid;else                   L = mid + 1;}return L;}
}

Python代码。自带的二分函数是bisect_left()。

import bisect
n = int(input())
a = list(map(int, input().split()))
a.sort()
ans = 0
cnt = 0
last = -1
last_id = n - 1
vis = [False] * n
for i in range(n - 1, -1, -1):if not vis[i]:cnt += 1ans += a[i]last = a[i]if cnt == 2:cnt = 0x = bisect.bisect_left(a, last // 2, 0, last_id)if x > last_id or a[x] > last // 2:  x -= 1if x >= 0:vis[x] = Truelast_id = x - 1
print(ans)

3.2 购物

链接:购物
  为方便处理,把硬币面值从小到大排序。
  无解是什么情况?如果没有面值1的硬币,组合不到1,无解。如果有面值1的硬币,那么所有的X都能满足,有解。所以,无解的充要条件是没有面值1的硬币。
  组合出1~X的任意值,需要的硬币多吗?学过二进制的人都知道,1、2、4、8、…、 2 n − 1 2^{n-1} 2n1这n个值,可以组合出1~ 2 n 2^n 2n-1的所有数。这说明,只需要很少的硬币,就能组合出很大的X。
  设已经组合出1~s的面值,即已经得到数字1、2、3、…、s,下一步扩展到s+1。当然,如果能顺便扩展到s+2、s+3、…扩展得越大越好,这样就能用尽量少的硬币扩展出更大的面值。
  如何扩展到s+1?就是在数字1、2、3、…、s的基础上,添加一个面值为v的硬币,得到s+1。v可以选1、2、…、s+1,例如:v=1,s+1=s+v;v=2,s+1=s-1+v;…;v=s+1,s+1=v。如果v=s+2,就不能组合到s+1了。
  v的取值范围是[1, s+1],为了最大扩展,选v为[1, s+1]内的最大硬币,此时s扩展到s+v。这就是贪心策略。
  以本题的输入样例为例说明计算过程。设答案为ans。
  先选硬币1,得到s=1。ans=1。
  再选[1, s+1]=[1, 2]内的最大硬币2,扩展s=1为s=1+v=3。ans=2。
  再选[1, s+1]=[1, 4]内的最大硬币2,得到s=5。ans=3。
  再选[1, s+1]=[1, 6]内的最大硬币5,得到s=10。ans=4。
  再选[1, s+1]=[1, 11]内的最大硬币10,得到s=20。ans=5。此时s≥X,结束。
  所以仅需5个面值1、2、2、5、10的硬币,就可以组合得到1、2、3、4、…、20。
  C/C++代码。第11行找[1, s]内的最大面值硬币,可以用二分法优化。本题不优化也能通过测试。

#include <bits/stdc++.h>
using namespace std;
int a[105];         //存硬币面值
int main(){int x,n;  cin >> x >>n;for(int i=0;i<n;i++) cin >> a[i];sort(a,a+n);if(a[0]!=1){ cout<<-1; return 0;}   //无解int s=0,ans=0;while(s<x)for(int v=n-1;v>=0;v--)if(a[v]<=s+1) {  //找到[1,s]内的最大面值硬币a[v]s+=a[v]; //扩展sans++;break;}cout << ans;
}

Java代码

import java.util.Arrays;
import java.util.Scanner;
public class Main {public static void main(String[] args) {Scanner input = new Scanner(System.in);int x = input.nextInt();int n = input.nextInt();int[] a = new int[n];for (int i = 0; i < n; i++)     a[i] = input.nextInt();        Arrays.sort(a);if (a[0] != 1) {  System.out.println(-1);  return; }int s = 0;int ans = 0;while (s < x) for (int v = n - 1; v >= 0; v--) if (a[v] <= s + 1) {s += a[v];ans++;break;}System.out.println(ans);}
}

python代码

x, n = map(int, input().split())
a = list(map(int, input().split()))
a.sort()
if a[0] != 1:  print(-1); exit()
s, ans = 0, 0
while s < x:for v in range(n - 1, -1, -1):if a[v] <= s + 1:s += a[v]ans += 1break
print(ans)

3.3 管道

2023年蓝桥杯省赛 Python B组 D题 10分
这10分似乎不难拿

链接:管道
  按题目的设定,管道内是贯通的,每个阀门都连着一个进水管,打开阀门后会有水从这个进水管进入管道,并逐渐流到管道内所有地方。
  先解释样例。设长度L的单位是米,水流的速度是米/秒。
  L=1处的阀门在第S=1秒打开,T=5秒时,覆盖范围L-(T-S)=1-(5-1)=-3,L+(T-S)=1+(5-1)=5;
  L=6处的阀门在S=5秒打开,T=5秒时,只覆盖了L=6;
  L=10处的阀门在L=2秒打开,T=5秒时,覆盖范围L-(T-S)=10-(5-2)=7,L+(T-S)=10+(5-2)=13。
  所以这3个阀门在T=5时,覆盖了[-3, 5]、6、[7,13],管道所有传感器都检测到了水流。
  读者可能立刻想到可以用二分法猜时间T。先猜一个T,然后判断在T时刻是否整个管道有水。如何判断?位于Li的阀门,它影响到的小区间是[Li-(Ti-Si), Li+(Ti-Si)],n个阀门对应了n个小区间。那么问题转化为:给出n个小区间,是否能覆盖整个大区间,这就是上一节提到的“区间覆盖问题”
  本题还可以再简单一点。题目给的评测用例指出Li-1 < Li,即已经按左端点排序了,可以省去排序的步骤。
  C++代码。在check((t)函数中,定义last_L为当前覆盖到的最左端,last_R为最右端。然后逐个遍历所有的小区间,看它对扩展last_L、last_R有无贡献。所有小区间处理完毕后,如果[last_L、last_R]能覆盖整个[1, len]区间,这个时刻t就是可行的。
  第32行把二分mid写成mid = ((R - L) >> 1) + L而不是mid = (R + L) >> 1,是因为R+L可能溢出。R的最大值是2e9,L的最大值是1e9,R+L超过了int的范围。为什么第30行定义R的初值为2e9?请读者思考。
C++代码

#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
const int LEN = 1e9;
int n, len;
int L[N], S[N];
bool check(int t){  // 检查t时刻,管道内是否都有水int cnt = 0;int last_L = 2, last_R = 1;for(int i = 0; i < n; i++)if(t >= S[i]){cnt++;      //特判t是否够大int left = L[i] - (t - S[i]);int right = L[i] + (t - S[i]);if(left < last_L)last_L = left, last_R = max(last_R, right);else if(left <= last_R + 1)last_R = max(last_R, right);}if(cnt == 0) return false;if(last_L <= 1 && last_R >= len)return true;elsereturn false;
}
int main(){scanf("%d%d", &n, &len);for(int i = 0; i < n; i++)scanf("%d%d", &L[i], &S[i]);int L = 0, R = 2e9, ans = -1;while(L <= R){                      //二分int mid = ((R - L) >> 1) + L;   //如果写成(L+R)>>1可能溢出if(check(mid)) ans = mid, R = mid - 1;else           L = mid + 1;}printf("%d\n", ans);return 0;
}

Java代码

import java.util.Scanner;
public class Main {static int[] L;static int[] S;static int n;static int len;public static boolean check(int t) {int cnt = 0;int last_L = 2;int last_R = 1;for(int i = 0; i < n; i++) {if(t >= S[i]) {cnt++;int left = L[i] - (t - S[i]);int right = L[i] + (t - S[i]);if(left < last_L) {last_L = left;last_R = Math.max(last_R, right);} else if(left <= last_R + 1) {last_R = Math.max(last_R, right);}}}if(cnt == 0) return false;if(last_L <= 1 && last_R >= len) return true;else return false;}public static void main(String[] args) {Scanner scanner = new Scanner(System.in);n = scanner.nextInt();len = scanner.nextInt();L = new int[n];S = new int[n];for(int i = 0; i < n; i++) {L[i] = scanner.nextInt();S[i] = scanner.nextInt();}int L = 0;int R = 2000000000;int ans = -1;while(L <= R) {int mid = ((R - L) >> 1) + L;if(check(mid)) {ans = mid;R = mid - 1;} else    L = mid + 1;            }System.out.println(ans);}
}

python代码

def check(t):cnt = 0last_L = 2last_R = 1for i in range(n):if t >= S[i]:cnt += 1left = L[i] - (t - S[i])right = L[i] + (t - S[i])if left < last_L:last_L = leftlast_R = max(last_R, right)elif left <= last_R + 1:last_R = max(last_R, right)if cnt == 0:      return Falseif last_L <= 1 and last_R >= length:   return Trueelse:        return Falsen, length = map(int, input().split())
L = []
S = []
for _ in range(n):l, s = map(int, input().split())L.append(l)S.append(s)
L_val,R_val =0, int(2e9)
ans = -1
while L_val <= R_val:mid = (R_val + L_val) >> 1if check(mid):ans = midR_val = mid - 1else:  L_val = mid + 1 
print(ans)

4. 习题

答疑 https://www.lanqiao.cn/problems/1025/learning/
身份证 https://www.lanqiao.cn/problems/3849/learning/
翻硬币 https://www.lanqiao.cn/problems/209/learning/
防御力 https://www.lanqiao.cn/problems/226/learning/
合并果子 https://www.luogu.com.cn/problem/P1090
排队接水 https://www.luogu.com.cn/problem/P1223
小A的糖果 https://www.luogu.com.cn/problem/P3817
负载平衡问题 https://www.luogu.com.cn/problem/P4016
找零钱 https://www.lanqiao.cn/problems/3854
01搬砖 https://www.lanqiao.cn/problems/2201/learning/
卡牌游戏 https://www.lanqiao.cn/problems/1057/learning
寻找和谐音符 https://www.lanqiao.cn/problems/3975/learning
三国游戏 https://www.lanqiao.cn/problems/3518/learning/
平均 https://www.lanqiao.cn/problems/3532/learning/
小蓝的旅行计划 https://www.lanqiao.cn/problems/3534/learning/
排座椅 https://www.luogu.com.cn/problem/P1056
母舰 https://www.luogu.com.cn/problem/P2813
加工生产调度 https://www.luogu.com.cn/problem/P1248

相关文章:

<蓝桥杯软件赛>零基础备赛20周--第11周--贪心

报名明年4月蓝桥杯软件赛的同学们&#xff0c;如果你是大一零基础&#xff0c;目前懵懂中&#xff0c;不知该怎么办&#xff0c;可以看看本博客系列&#xff1a;备赛20周合集 20周的完整安排请点击&#xff1a;20周计划 每周发1个博客&#xff0c;共20周。 在QQ群上答疑&#x…...

PowerShell Instal 一键部署TeamCity

前言 TeamCity 是一个通用的 CI/CD 软件平台,可实现灵活的工作流程、协作和开发实践。允许在您的 DevOps 流程中成功实现持续集成、持续交付和持续部署。 系统支持 Centos7,8,9/Redhat7,8,9及复刻系列系统支持 Windows 10,11,2012,2016,2019,2022高版本建议使用9系列系统…...

将“渴望“乐谱写入AT24C02并读出播放

#include <reg51.h> // 包含51单片机寄存器定义的头文件 #include <intrins.h> //包含_nop_()函数定义的头文件 #define OP_READ 0xa1 // 器件地址以及读取操作,0xa1即为1010 0001B #define OP_WRITE 0xa0 // 器件地址以及写…...

Vue独立组件开发-动态组件

文章目录 一、前言二、实现三、优化四、总结五、最后 一、前言 在开发中&#xff0c;你经常会遇到这么一种情况&#xff1a;根据条件动态地切换某个组件&#xff0c;或动态地选择渲染某个组件。 Vue 提供了另外一个内置的组件 <component> 和 is 特性&#xff0c;可以更…...

前端八股文(HTML篇)

目录 1.什么是DOCTYPE,有何用呢&#xff1f; 2.说说对html语义化的理解 3.src和href的区别&#xff1f; 4.title与h1的区别&#xff0c;b与strong的区别&#xff0c;i与em的区别&#xff1f; 5.什么是严格模式与混杂模式&#xff1f; 6.前端页面有哪三层构成&#xff0c;分…...

RivaGAN 水印项目

git地址 https://github.com/DAI-Lab/RivaGAN Dockerfile (/tools下文件为git下的文件) ############################################### # 使用 NVIDIA CUDA 10.0 开发环境作为基础镜像 FROM kaldiasr/kaldi:gpu-ubuntu18.04-cuda10.0 # 设置非交互式安装模式以避免某些命…...

Games101作业5

1.实现Renderer.cpp 中的 Render()&#xff1a;为每个像素生成光线 这里你需要为每个像素生成一条对应的光 线&#xff0c;然后调用函数 castRay() 来得到颜色&#xff0c;最后将颜色存储在帧缓冲区的相 应像素中。 我们要做的就是将屏幕空间下的坐标最后转换到世界空间的坐标…...

Golang解决跨域问题【OPTIONS预处理请求】

Golang解决跨域问题 前置知识&#xff1a;跨域问题产生条件及原因 跨域是是因为浏览器的同源策略限制&#xff0c;是浏览器的一种安全机制&#xff0c;服务端之间是不存在跨域的。 所谓同源指的是两个页面具有相同的协议、主机和端口&#xff0c;三者有任一不相同即会产生跨域…...

复试 || 就业day05(2023.12.31)算法篇

文章目录 前言找不同最长回文串找到所有数组中消失的数字下一个更大元素 I键盘行 前言 &#x1f4ab;你好&#xff0c;我是辰chen&#xff0c;本文旨在准备考研复试或就业 &#x1f4ab;文章题目大多来自于 leetcode&#xff0c;当然也可能来自洛谷或其他刷题平台 &#x1f4ab…...

Spring-4-代理

前面提到过&#xff0c;在Spring中有两种类型的代理&#xff1a;使用JDK Proxy类创建的JDK代理以及使用CGLIB Enhancer类创建的基于CGLIB的代理。 你可能想知道这两种代理之间有什么区别&#xff0c;以及为什么 Spring需要两种代理类型。 在本节中&#xff0c;将详细研究代理…...

设计模式:抽象工厂模式(讲故事易懂)

抽象工厂模式 定义&#xff1a;将有关联关系的系列产品放到一个工厂里&#xff0c;通过该工厂生产一系列产品。 设计模式有三大分类&#xff1a;创建型模式、结构型模式、行为型模式 抽象工厂模式属于创建型模式 上篇 工厂方法模式 提到工厂方法模式中每个工厂只生产一种特定…...

C语言中的Strict Aliasing Rule

文章目录 前言没有警告不代表没有问题目前的应对方法 前言 很久没写了&#xff0c;水一篇。 最近有个代码在gcc 4.8.5上编译失败。编译失败的提示是&#xff1a; error: dereferencing type-punned pointer will break strict-aliasing rules [-Werrorstrict-aliasing]查了下…...

单字符检测模型charnet使用方法,极简

Git链接 安装按照上面的说明&#xff0c;说下使用。 把tools下面的test做了一点修改&#xff0c;可以读取一张图片&#xff0c;把里面的单个字符都检测和识别出来。 然后绘制到屏幕上。 import torch from charnet.modeling.model import CharNet import cv2, os import num…...

Erlang、RabbitMQ下载与安装教程(windows超详细)

目录 安装Erlang 1.首先安装RabbitMQ需要安装Erlang环境 2.点击下载好的.exe文件进行傻瓜式安装,一直next即可 3.配置Erlang环境变量 安装RabbitMQ 1.给出RabbitMQ官网下载址&#xff1a;Installing on Windows — RabbitMQ&#xff0c;找到 2.配置RabbitMQ环境变量&#xff0…...

2023年终总结丨很苦,很酷!

文章目录 个人简介丨了解博主写在前面丨博主介绍年终总结丨博主成就年终总结丨博主想说年终总结丨学习芝士年终总结丨未来展望写在后面丨新年快乐 个人简介丨了解博主 主页地址&#xff1a;https://blog.csdn.net/m0_68111267 荣誉身份 ⭐2022年度CSDN 社区之星 Top6 ⭐2023年…...

鸿蒙 DevEco Studio 3.1 入门指南

本文主要记录开发者入门&#xff0c;从软件安装到项目运行&#xff0c;以及后续的学习 1&#xff0c;配置开发环境 1.1 下载安装包 官网下载链接 点击立即下载找到对应版版本 下载完成&#xff0c;按照提示默认安装即可 1.2 下载SDK及工具链 运行已安装的DevEco Studio&…...

ubuntu多用户环境dockerbug,卸载重装docker流程

之前不小心误操作删除重装docker&#xff0c;结果删除没成功&#xff0c;更没法重装&#xff0c;每次apt install都会报一个docker错误&#xff0c;虽然不影响软件的常规安装&#xff5e;但是现在还是需要装一个完整docker&#xff0c;还是选择删除一下&#xff0c;重点是关闭服…...

微信小程序开发系列-09自定义组件样式特性

微信小程序开发系列目录 《微信小程序开发系列-01创建一个最小的小程序项目》《微信小程序开发系列-02注册小程序》《微信小程序开发系列-03全局配置中的“window”和“tabBar”》《微信小程序开发系列-04获取用户图像和昵称》《微信小程序开发系列-05登录小程序》《微信小程序…...

数据结构 模拟实现LinkedList单向不循环链表

目录 一、链表的简单介绍 二、链表的接口 三、链表的方法实现 &#xff08;1&#xff09;display方法 &#xff08;2&#xff09;size得到单链表的长度方法 &#xff08;3&#xff09;addFirst头插方法 &#xff08;4&#xff09;addLast尾插方法 &#xff08;5&#xf…...

2023-12-24 LeetCode每日一题(收集足够苹果的最小花园周长)

2023-12-24每日一题 一、题目编号 1954. 收集足够苹果的最小花园周长二、题目链接 点击跳转到题目位置 三、题目描述 给你一个用无限二维网格表示的花园&#xff0c;每一个 整数坐标处都有一棵苹果树。整数坐标 (i, j) 处的苹果树有 |i| |j| 个苹果。 你将会买下正中心坐…...

Oracle 19c OCP 1z0 082考场真题解析第17题

考试科目&#xff1a;1Z0-082 考试题量&#xff1a;90 通过分数&#xff1a;60% 考试时间&#xff1a;150min 本文为云贝教育郭一军guoyJoe原创&#xff0c;请尊重知识产权&#xff0c;转发请注明出处&#xff0c;不接受任何抄袭、演绎和未经注明出处的转载。 17. Which three …...

掌握这十几个Python库才是爬虫界的天花板,没有你搞不定的网站!实战案例:Python全网最强电影搜索工具,自动生成播放链接

掌握这十几个Python库才是爬虫界的天花板,没有你搞不定的网站!实战案例:Python全网最强电影搜索工具,自动生成播放链接。 用来爬虫的十几个Python库。只要正确选择适合自己的Python库才能真正提高爬虫效率,到达高效爬虫目的。 1.PyQuery from pyquery import PyQuery as …...

模型 KANO卡诺模型

本系列文章 主要是 分享 思维模型&#xff0c;涉及各个领域&#xff0c;重在提升认知。需求分析。 1 卡诺模型的应用 1.1 餐厅需求分析故事 假设你经营一家餐厅&#xff0c;你想了解客户对你的服务质量的满意度。你可以使用卡诺模型来收集客户的反馈&#xff0c;并分析客户的…...

启明智显开源项目分享|基于Model 3c芯片的86中控面板ZX3D95CM20S-V11项目软硬件全开源

前言&#xff1a; 本文为4寸 480*480 RGB接口IPS全面触屏的86中控面板&#xff08;RT-ThreadLVGL&#xff09;软硬件开源干货内容&#xff0c;该项目是综合性非常强的RTOS系列项目&#xff01;项目主控芯片使用 Model 3c&#xff0c;整体实现了简化版本的86中控面板的功能需求…...

Kind创建k8s - JAVA操作控制

kind 简介kind 架构安装 Kind (必备工具)docker官网kubectl官网kind官网校验安装结果 关于kind 命令 安装一个集群查看当前 Kubernetes 集群中的节点信息。查看当前命名空间下中的Pod&#xff08;容器实例&#xff09;的信息。使用 kind create cluster 安装&#xff0c;关于安…...

Qt sender()函数

sender函数原型&#xff1a; QObject *sender() const; 如果在由信号激活的插槽中调用该函数&#xff0c;返回指向发送信号的对象的指针&#xff0c;否则返回0&#xff0c;该指针仅在从该对象的线程上下文调用此函数的槽执行期间有效。 主要代码如下&#xff1a; 其中运用了Q…...

Java开发框架和中间件面试题(6)

目录 61.什么是Spring Batch&#xff1f; 62.请举例解释Required与Qualifier注解&#xff1f; 61.什么是Spring Batch&#xff1f; Spring batch是一个轻量级的&#xff0c;完善的批处理框架&#xff0c;他主要的目的在于帮助企业建立健壮&#xff0c;高效的批处理应用。Spri…...

附录E SQL入门之SQL保留字

本专栏目录 第1课 SQL入门之了解SQL 第2课 SQL入门之检索数据 第3课 SQL入门之排序检索数据 第4课 SQL入门之过滤数据 第5课 SQL入门之高级数据过滤 第6课 SQL入门之用通配符进行过滤 第7课 SQL入门之创建计算字段 第8课 SQL入门之使用数据处理函数 第9课 SQL入门之汇总数据 第…...

thinkphp6.0升级到8.0

目录 一&#xff1a;升级过程 二&#xff1a;报错处理 最近写的项目需要使用thinkphp8.0&#xff0c;之前的老项目需要从php6.0升级到8.0&#xff0c;特此记录下升级过程。 一&#xff1a;升级过程 查看版本&#xff1a; php think version,我目前的版本是6.1.4 生成thin…...

机器学习(一) -- 概述

系列文章目录 机器学习&#xff08;一&#xff09; -- 概述 机器学习&#xff08;二&#xff09; -- 数据预处理 未完待续…… 目录 系列文章目录 前言 一、机器学习定义&#xff08;是什么&#xff09; 二、机器学习的应用&#xff08;能做什么&#xff09; 三、***机器…...

SpringBoot定时监听RocketMQ的NameServer

问题分析 自己在测试环境部署了RocketMQ&#xff0c;发现namesrv很容易挂掉&#xff0c;于是就想着监控&#xff0c;挂了就发邮件通知。查看了rocketmq-dashboard项目&#xff0c;发现只能监控Broker&#xff0c;遂放弃这一路径。于是就从报错的日志入手&#xff0c;发现最终可…...

电子招标采购系统源码之从供应商管理到采购招投标、采购合同、采购执行的全过程数字化管理

在数字化时代&#xff0c;采购管理也正经历着前所未有的变革。全过程数字化采购管理成为了企业追求高效、透明和规范的关键。该系统通过Spring Cloud、Spring Boot2、Mybatis等先进技术&#xff0c;打造了从供应商管理到采购招投标、采购合同、采购执行的全过程数字化管理。通过…...

各部门请注意,VELO维乐潮流骑士尼莫出街啦,快来加入吧!

VELO潮流骑士丨车界“小学生”尼莫&#xff0c;下面是来自她的自诉&#xff1a;      大家好&#xff01;我是尼莫&#xff0c;一枚骑车届的“小学生”&#xff0c;我爱上骑车已经有一年的时间啦&#xff01;在这一年的时间里&#xff0c;骑车改变了我很多&#xff1a;爱上…...

Flutter配置Android和IOS允许http访问

默认情况下&#xff0c;Android和IOS只支持对https的访问&#xff0c;如果需要访问不安全的连接&#xff0c;也就是http&#xff0c;需要做以下配置。 Android 在res目录下的xml目录中(如果不存在&#xff0c;先创建xml目录)&#xff0c;创建一个xml文件network_security_con…...

[设计模式 Go实现] 创建型~抽象工厂模式

抽象工厂模式用于生成产品族的工厂&#xff0c;所生成的对象是有关联的。 如果抽象工厂退化成生成的对象无关联则成为工厂函数模式。 比如本例子中使用RDB和XML存储订单信息&#xff0c;抽象工厂分别能生成相关的主订单信息和订单详情信息。 如果业务逻辑中需要替换使用的时候…...

移动端开发框架mui代码在安卓模拟器上运行(HbuilderX连接到模拟器)

开发工具 HBuilder X 3.8.12.20230817 注意&#xff1a;开发工具尽量用最新的或较新的。太旧的版本在开发调试过程中可能会出现莫名其妙的问题。 1、电脑下载安装安卓模拟器 我这里使用的是 夜神模拟器 &#xff0c;也可以选择其他安卓模拟器 夜神模拟器官网&#xff1a;夜神安…...

upload-labs Pass-03(黑名单验证,特殊后缀)问题纠正

php任何后缀名解析 背景&#xff1a;为了验证php解析不依靠后缀名&#xff0c;可以是任何后缀名&#xff0c;纠正upload-labs Pass-03&#xff08;黑名单验证&#xff0c;特殊后缀&#xff09;里所说的几个固定的后缀名理论是错误的。1 部署1.1 环境准备1.1.1 系统、内核&#…...

微信小程序-父子页面传值

父子页面传值 父页面向子页面传值 方法一&#xff1a; 父页面&#xff1a; 1. /page/xxx/xxx?id1子页面&#xff1a; onLoad:function(option){ }方法二 <bindtap“func” data-xxx””> 子页面向父页面传值 定义父子页面 父页面&#xff1a;hotspot 子页面&a…...

【JavaScript】浮点数精度问题

✨ 专栏介绍 在现代Web开发中&#xff0c;JavaScript已经成为了不可或缺的一部分。它不仅可以为网页增加交互性和动态性&#xff0c;还可以在后端开发中使用Node.js构建高效的服务器端应用程序。作为一种灵活且易学的脚本语言&#xff0c;JavaScript具有广泛的应用场景&#x…...

使用axios发送get和post请求

使用axios发送get和post请求的方法如下&#xff1a; 1.发送GET请求&#xff1a; axios.get(url).then(response > {// 请求成功的处理逻辑console.log(response.data);}).catch(error > {// 请求失败的处理逻辑console.error(error);});2.发送POST请求&#xff1a; ax…...

【基于VirtualBox及openEuler20.03 TLS SP1编译openGauss2.1.0源码】

【openEuler 20.03 TLS编译openGauss2.1.0源码】 一、安装环境二、安装步骤 一、安装环境 项目Value虚拟机virtualbox操作系统openEuler 20.03 TLSopenGauss2.1.0openGauss-third_party2.1.0 二、安装步骤 以下操作需要在root用户下执行 编辑/etc/selinux/config vim /etc/s…...

hibernate 使用注解+拦截器实现自动开启、关闭session,提交、回滚事务

hibernate 使用注解+注解拦截器实现自动开启、关闭session,开启、提交、回滚事务 项目为springboot项目 ,springboot版本为:2.5.11, hiernate-core5.4.3 版本。spring-xxx 等为5.3.17版本 注意:在spring-xxx4.x版本+ hiernate-core5.x.x版本中,hibernate的配置 true是有效的…...

Solidworks学习笔记

本内容为solidworks的学习笔记&#xff0c;根据自己的理解进行记录&#xff0c;部分可能不正确&#xff0c;请自行判断。 学习视频参考&#xff1a;【SolidWorks2018视频教程 SW2018中文版软件基础教学知识 SolidWorks自学教程软件操作教程 sw视频教程 零基础教程 视频教程】 h…...

Redis经典五大类型源码及底层实现(一)

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱吃芝士的土豆倪&#xff0c;24届校招生Java选手&#xff0c;很高兴认识大家&#x1f4d5;系列专栏&#xff1a;Spring源码、JUC源码、Kafka原理、分布式技术原理、数据库技术&#x1f525;如果感觉博主的文章还不错的…...

数据库闭包求法 附相关习题及解析

闭包就是由一个属性直接或间接推导出的所有属性的集合 以下是写的比较科学规范的闭包求解方法&#xff0c;设X和Y均为关系R的属性集的子集&#xff0c;F是R上的函数依赖集&#xff0c;若对R的任一属性集B&#xff0c;一旦X→B&#xff0c;必有B⊆Y&#xff0c;且对R的任一满足…...

idea利用JRebel插件,无需重启,实现Spring Boot项目热重载,节省开发时间和精力!

插件介绍 官方介绍 翻译过来的意思是&#xff1a; JRebel 是一款提高开发效率的工具&#xff0c;允许开发者立即重新加载代码更改。它跳过了在Java开发中常见的重新构建、重启和重新部署循环。JRebel 能够让开发者在相同的时间内完成更多工作&#xff0c;并且在编码时能够保持…...

学习体系结构 - AArch64内存管理

学习体系结构 - AArch64内存管理 Learn the architecture - AArch64 memory management Version 1.2 个人的英语很一般&#xff0c;对拿不准的翻译校准在后面添加了英文原文。 1、 概述 本指南介绍了AArch64中的内存转换&#xff0c;这是内存管理的关键。它解释了如何将虚拟地…...

Vue3 精通指南:如何在 setup 函数中巧妙利用 Vuex

在 Vue 3 中&#xff0c;如果你使用了组合式 API&#xff08;Composition API&#xff09;&#xff0c;你可以通过 setup 函数来设置组件的响应式状态和逻辑。要在 setup 函数中访问 Vuex 的 $store&#xff0c;你可以使用 useStore 钩子&#xff0c;它是 Vuex 4 为 Vue 3 提供…...

Linux 服务器安全策略技巧:启用账户锁定策略

Linux 服务器安全策略技巧:启用账户锁定策略 在Linux服务器上,启用账户锁定策略是一种重要的安全措施。通过锁定账户,可以防止未经授权的访问和恶意活动。本文将介绍如何在Linux服务器上启用账户锁定策略。 什么是账户锁定策略? 账户锁定策略是一种安全措施,用于限制对…...

野火霸道-V2+3.2寸屏+FreeRTOS+LVGL移植

摘要 基于野火霸道-V23.2寸屏的开发板&#xff0c;下载器为STLINK分为两个版本&#xff0c;FreeRTOS和裸机版本 裸机 裸机准备 lvgl v8.2版本的源码野火的《触摸画板-3.2寸》与《基本定时器》的代码例程 移植 将基本定时器代码移植到触摸画板-3.2寸的例程中&#xff0c;…...