当前位置:   article > 正文

2023年第十四届蓝桥杯JavaB组省赛真题(题目+全部完整题解)_蓝桥杯题目

蓝桥杯题目

目录

A、阶乘求和

 Ⅰ、题目解读

Ⅱ、代码 

B、幸运数字

 Ⅰ、题目解读

 Ⅱ、代码

C: 数组分割(时间限制: 1.0s 内存限制: 512.0MB)

 Ⅰ、解题思路

 Ⅱ、代码

 D、矩形总面积(时间限制: 1.0s 内存限制: 512.0MB)

 Ⅰ、题目解读

Ⅱ、代码 

 E、蜗牛(时间限制: 1.0s 内存限制: 512.0MB)

 Ⅰ、题目解读

 Ⅱ、代码

 F、合并区域 (时间限制: 2.0s 内存限制: 512.0MB)

 Ⅰ、题目解读

 Ⅱ、代码

 G、买二赠一(时间限制: 1.0s 内存限制: 512.0MB)

 Ⅰ、题目解读

 Ⅱ、代码1(复杂度过大,超时)

代码2(正确答案)

 H、合并石子(时间限制: 1.0s 内存限制: 512.0MB)

 Ⅰ、题目解读

Ⅱ、代码

 I、最大开支(时间限制: 1.0s 内存限制: 512.0MB )

 Ⅰ、题目解读

 J、魔法阵(时间限制: 1.0s 内存限制: 512.0MB )

 总结


2023年第十四届蓝桥杯JavaB组省赛文件已上传到csdn,可自行下载

蓝桥杯题目:2023年第十四届蓝桥杯大赛软件类省赛Java大学B组真题 - 题库 - C语言网 (dotcpp.com)

详细完整题解在这篇博客:

2023年第十四届蓝桥杯省赛JavaB组个人题解(AK)_迷你滨的博客-CSDN博客

A、阶乘求和

【问题描述】
S = 1! + 2! + 3! + ... + 202320232023! ,求 S 的末尾 9 位数字。
提示:答案首位不为 0

 Ⅰ、题目解读

 一看到三个2023的巨大数字,我想大家应该都人都麻了。但是我想说这是官方的骗术,因为题目说要求末尾的9位数,其实我想告诉大家当加到40多的阶乘时,这个阶乘和后面的9位数就不会发生改变了。

Ⅱ、代码 

  1. public class Main {
  2. public static void main(String[] args) {
  3. long start=1;
  4. String s="202320232023";
  5. long end= Long.parseLong(s);
  6. long sum=0;
  7. long cj=1;
  8. while (start<=end){
  9. cj*=start;
  10. cj%=1000000000;
  11. sum+=cj;
  12. sum%=1000000000;
  13. start++;
  14. if (start>40)
  15. System.out.println(sum);
  16. }
  17. System.out.println(sum);
  18. }
  19. }

 看运行

  1. 20940313
  2. 420940313
  3. 420940313
  4. 420940313
  5. 420940313
  6. 420940313
  7. 420940313
  8. ...

这是因为40的阶乘之后后面 9位数都是0,所以阶乘之和末尾9位数不会再发生改变!

B、幸运数字

【问题描述】
哈沙德数是指在某个固定的进位制当中,可以被各位数字之和整除的正整 数。例如 126 是十进制下的一个哈沙德数,因为 (126) 10 mod (1+2+6) = 0 126 也是八进制下的哈沙德数,因为 (126) 10 = (176) 8 (126) 10 mod (1 + 7 + 6) = 0 ; 同时 126 也是 16 进制下的哈沙德数,因为 (126) 10 = (7 e ) 16 (126) 10 mod (7 + e ) = 0 。小蓝认为,如果一个整数在二进制、八进制、十进制、十六进制下均为 哈沙德数,那么这个数字就是幸运数字,第 1 至第 10 个幸运数字的十进制表示 为:1 , 2 , 4 , 6 , 8 , 40 , 48 , 72 , 120 , 126 . . . 。现在他想知道第 2023 个幸运数 字是多少?你只需要告诉小蓝这个整数的十进制表示即可。

 Ⅰ、题目解读

 这题就是考察大家的进制转换,数据量也不大。直接看代码吧!

 Ⅱ、代码

  1. public class {
  2. public static void main(String[] args) {
  3. int j=0;
  4. for (int i=1;i<10000000;i++){
  5. if (BaseConversion(i)){
  6. j++;
  7. if (j==2023){
  8. System.out.println(i);//215040
  9. break;
  10. }
  11. }
  12. }
  13. }
  14. public static boolean BaseConversion(int n){
  15. //十进制
  16. int sum=0;
  17. int x=n;
  18. while (x!=0){
  19. sum+=(x%10);
  20. x/=10;
  21. }
  22. if (n%sum!=0)
  23. return false;
  24. //二进制
  25. sum=0;
  26. x=n;
  27. while (x!=0){
  28. sum+=(x%2);
  29. x/=2;
  30. }
  31. if (n%sum!=0)
  32. return false;
  33. //八进制
  34. sum=0;
  35. x=n;
  36. while (x!=0){
  37. sum+=(x%8);
  38. x/=8;
  39. }
  40. if (n%sum!=0)
  41. return false;
  42. //十六进制
  43. int[] arr={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
  44. sum=0;
  45. x=n;
  46. while (x!=0){
  47. sum+=(arr[x%16]);
  48. x/=16;
  49. }
  50. if (n%sum!=0)
  51. return false;
  52. return true;
  53. }
  54. }

C: 数组分割(时间限制: 1.0s 内存限制: 512.0MB)

时间限制 : 1.0s
内存限制 : 512.0MB
本题总分: 10
【问题描述】
小蓝有一个长度为 N 的数组 A = [ A 0 , A 1 , . . . , A N 1 ] 。现在小蓝想要从 A 对应的数组下标所构成的集合 I = { 0 , 1 , 2 , . . . , N 1 } 中找出一个子集 R 1 ,那么 R 1在 I 中的补集为 R 2 。记 S 1 = r R 1 A r S 2 = r R 2 A r,我们要求 S 1 S 2 均为 偶数,请问在这种情况下共有多少种不同的 R 1。当 R1 或 R 2 为空集时我们将 S 1 S 2 视为 0。

【输入格式】
第一行一个整数 T ,表示有 T 组数据。 接下来输入 T 组数据,每组数据包含两行:第一行一个整数 N ,表示数组 A 的长度;第二行输入 N 个整数从左至右依次为 A 0 , A 1 , . . . , A N 1 ,相邻元素之 间用空格分隔。
【输出格式】
对于每组数据,输出一行,包含一个整数表示答案,答案可能会很大,你
需要将答案对 1000000007 进行取模后输出。
【样例输入】
  1. 2
  2. 2
  3. 6 6
  4. 2
  5. 1 6
【样例输出】
4
【样例说明】
对于第一组数据,答案为 4 。(注意:大括号内的数字表示元素在数组中的下标。)
R 1 = { 0 } , R 2 = { 1 } ;此时 S 1 = A 0 = 6 为偶数 , S 2 = A 1 = 6 为偶数。
R 1 = { 1 } , R 2 = { 0 } ;此时 S 1 = A 1 = 6 为偶数 , S 2 = A 0 = 6 为偶数。
R 1 = { 0 , 1 } , R 2 = {} ;此时 S 1 = A 0 + A 1 = 12 为偶数 , S 2 = 0 为偶数。
R 1 = {} , R 2 = { 0 , 1 } ;此时 S 1 = 0 为偶数 , S 2 = A 0 + A 1 = 12 为偶数。
对于第二组数据,无论怎么选择,都不满足条件,所以答案为 0
【评测用例规模与约定】
对于 20 % 的评测用例, 1 N 10
对于 40 % 的评测用例, 1 N 10 2
对于 100 % 的评测用例, 1 T 10 , 1 N 10 3 , 0 A i 10 9  

 Ⅰ、解题思路

要求分割两个子集,其中一个可以为空集,且两个集合为偶数,所有第一步判断集合的总和是否为偶数,如果不为偶数则直接判定为 0 个否则再进行深度收搜判断 (暴力超时)

也可以利用奇数个数与偶数个数的排列组合实现, 将两个奇数拼接为一个偶数,判断无重复的奇数拼接情况,与偶数个数相加,递推排列组合公式  (正解)

优化排列组合,会发现是高精度算法 设 x 为偶数个数, y 为奇数个数ans = pow(x + (y == 0 ? 0 : y - 1)) % mod 算法标签:递推,找规律,贪心


注意事项:
 x + (y == 0 ? 0 : y - 1), 奇数为0情况

 Ⅱ、代码

  1. //排列组合递推公式
  2. import java.util.Scanner;
  3. import java.math.BigInteger;
  4. public class Main {
  5. public static final BigInteger MOD = new BigInteger("1000000007");
  6. public static void main(String[] args) {
  7. Scanner scan = new Scanner(System.in);
  8. int T = scan.nextInt();
  9. while (T-- > 0){
  10. int n = scan.nextInt();
  11. int[] a = new int[n];
  12. long x = 0, y = 0; // x 记录偶数, y 记录奇数
  13. for(int i = 0; i < n; i++){
  14. a[i] = scan.nextInt() % 2;
  15. if(a[i] == 0){
  16. x++;
  17. }else {
  18. y++;
  19. }
  20. }
  21. if(y % 2 == 1){ // 奇数个数为奇,没有一个条件成立
  22. System.out.println(0);
  23. continue;
  24. }
  25. x = x + (y == 0 ? 0 : y - 1); // 两个奇数组合为一个偶数,排除重复情况
  26. BigInteger ans = new BigInteger("2");
  27. BigInteger dp = new BigInteger("1");
  28. // C(n,m) = P(n,m) / P(m,m) = n! / m! * (n - m)!
  29. // 转移递推公式 dp = (dp * (x, x-1, x-2, ... , n) / (1, 2, 3, ... , n))
  30. for(long i = 1, j = x; i < x; i++, j--){ // 排列组合无顺序 C
  31. BigInteger u = new BigInteger(String.valueOf(j));
  32. BigInteger v = new BigInteger(String.valueOf(i));
  33. dp = dp.multiply(u).divide(v);
  34. ans = ans.add(dp);
  35. }
  36. System.out.println(ans.mod(MOD));
  37. }
  38. }
  39. }

  优化高精度

  1. import java.util.Scanner;
  2. import java.math.BigInteger;
  3. public class Main {
  4. public static final BigInteger MOD = new BigInteger("1000000007");
  5. public static final BigInteger TWO = new BigInteger("2");
  6. public static void main(String[] args) {
  7. Scanner scan = new Scanner(System.in);
  8. int T = scan.nextInt();
  9. while (T-- > 0) {
  10. int n = scan.nextInt();
  11. int x = 0, y = 0; // x 记录偶数, y 记录奇数
  12. for (int i = 0; i < n; i++) {
  13. int a = scan.nextInt() % 2;
  14. if (a == 0) {
  15. x++;
  16. } else {
  17. y++;
  18. }
  19. }
  20. if (y % 2 == 1) {
  21. System.out.println(0);
  22. }else{
  23. System.out.println(TWO.pow(x + (y == 0 ? 0 : y - 1)).mod(MOD));
  24. }
  25. }
  26. }
  27. }

 D、矩形总面积(时间限制: 1.0s 内存限制: 512.0MB)

【问题描述】
平面上有个两个矩形 R 1 R 2 ,它们各边都与坐标轴平行。设 ( x 1 , y 1 ) 和 (x 2 , y 2 ) 依次是 R 1 的左下角和右上角坐标, ( x 3 , y 3 ) ( x 4 , y 4 ) 依次是 R 2 的左下 角和右上角坐标,请你计算 R 1 R 2 的总面积是多少?
注意:如果 R 1 R 2 有重叠区域,重叠区域的面积只计算一次。
【输入格式】
输入只有一行,包含 8 个整数,依次是: x 1 y 1 x 2 y 2 x 3 y 3 x 4 y 4
【输出格式】
一个整数,代表答案。
【样例输入】
2 1 7 4 5 3 8 6
【样例输出】
22
【样例说明】
样例中的两个矩形如图所示:

【评测用例规模与约定】
对于 20 % 的数据, R 1 R 2 没有重叠区域。
对于 20 % 的数据,其中一个矩形完全在另一个矩形内部。
对于 50 % 的数据,所有坐标的取值范围是 [0 , 10³  ]
对于 100 % 的数据,所有坐标的取值范围是 [0 , 10 ]

 Ⅰ、题目解读

这题有两种解法,自己数组去求,但是可能数据量过大会爆栈。第二种就是公式直接求解,这时求两个矩形相交的面积改怎么求?

矩形相交要使条件成立,即min(x2,x4)-max(x1,x3)>=0 且min(y2,y4)-max(y1,y3)>=0
如果条件成立,则相交矩形面积为:(min(x2,x4)-max(x1,x3))* (min(y2,y4)-max(y1,y3))

Ⅱ、代码 

  1. import java.util.Scanner;
  2. public class Main {
  3. public static void main(String[] args) {
  4. Scanner sc = new Scanner(System.in);
  5. int x1 = sc.nextInt();
  6. int y1 = sc.nextInt();
  7. int x2 = sc.nextInt();
  8. int y2 = sc.nextInt();
  9. int x3 = sc.nextInt();
  10. int y3 = sc.nextInt();
  11. int x4 = sc.nextInt();
  12. int y4 = sc.nextInt();
  13. long area1 = (long) (x2 - x1) * (y2 - y1); // 计算第一个矩形的面积
  14. long area2 = (long) (x4 - x3) * (y4 - y3); // 计算第二个矩形的面积
  15. long overlapArea=0;
  16. long l = Math.min(x2, x4) - Math.max(x1, x3);
  17. long w= Math.min(y2,y4)-Math.max(y1,y3);
  18. if (l >=0&&w >=0){
  19. overlapArea= l * w;
  20. }
  21. long Area = area1 + area2 - overlapArea; // 总面积
  22. System.out.println(Area); // 输出总面积
  23. }
  24. }

 E、蜗牛(时间限制: 1.0s 内存限制: 512.0MB

【问题描述】
这天,一只蜗牛来到了二维坐标系的原点。 在 x 轴上长有 n 根竹竿。它们平行于 y 轴,底部纵坐标为 0 ,横坐标分别 为 x 1 , x 2 , ..., x n 。竹竿的高度均为无限高,宽度可忽略。蜗牛想要从原点走到第 n 个竹竿的底部也就是坐标 ( x n , 0) 。它只能在 x 轴上或者竹竿上爬行,在 x
上爬行速度为 1 单位每秒;由于受到引力影响,蜗牛在竹竿上向上和向下爬行 的速度分别为 0 . 7 单位每秒和 1 . 3 单位每秒。 为了快速到达目的地,它施展了魔法,在第 i i + 1 根竹竿之间建立了传 送门(0 < i < n ),如果蜗牛位于第 i 根竹竿的高度为 a i 的位置 ( x i , a i ) ,就可以 瞬间到达第 i + 1 根竹竿的高度为 b i +1 的位置 ( x i +1 , b i +1 ), 请计算蜗牛最少需要多少秒才能到达目的地。
【输入格式】
输入共 1 + n 行,第一行为一个正整数 n
第二行为 n 个正整数 x 1 , x 2 , . . . , x n
后面 n 1 行,每行两个正整数 a i , b i +1
【输出格式】
输出共一行,一个浮点数表示答案( 四舍五入保留两位小数 )。
【样例输入】
  1. 3
  2. 1 10 11
  3. 1 1
  4. 2 1

【样例输出

4.20
【样例说明】
蜗牛路线:
(0 , 0) (1 , 0) (1 , 1) (10 , 1) (10 , 0) (11 , 0) ,花费时间为 1 +1/  0.7 + 0 + 1/1 .3 + 1 4 . 20
【评测用例规模与约定】
对于 20 % 的数据,保证 n 15
对于 100 % 的数据,保证 n ≤ 10a i , b i ≤ 10x i ≤ 10

 Ⅰ、题目解读

dp[i][j] 表示蜗牛走到第 i 根杆子的最短用时,j 表示状态。
j = 0 : 走到杆子底部
j = 1 :走到杆子的传送门处
P.S.由于只与前一个杆子状态有关,其实用两个变量就行,用二维数组便于理解
时间复杂度: O(n)

 Ⅱ、代码

  1. import java.io.*;
  2. import java.util.*;
  3. public class Main{
  4. static int maxn = 200005,n,m;
  5. static long INF = (long)2e18,ans = 0,mod = (int)1e9+7;
  6. static Scanner sc = new Scanner (System.in);
  7. static BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
  8. static StreamTokenizer st =new StreamTokenizer(bf);
  9. static PrintWriter pw = new PrintWriter(new OutputStreamWriter(System.out));
  10. public static void main(String[]args) throws IOException{
  11. int T = 1;
  12. //T = Integer.parseInt(S());
  13. while(T-->0) solve();
  14. pw.flush();
  15. }
  16. static final int I() throws IOException {
  17. st.nextToken();
  18. return (int)st.nval;
  19. }
  20. static void solve() throws IOException{
  21. n = I();
  22. long x[] = new long [n+1];
  23. for(int i=1;i<=n;i++) x[i] = I();
  24. int []a = new int [n+1];
  25. int []b = new int [n+1];
  26. for(int i=1;i<n;i++) {
  27. a[i] = I();b[i] = I();
  28. }
  29. double dp[][] = new double[n+1][2];
  30. dp[1][0] = x[1]; //底端最小用时
  31. dp[1][1] = x[1] + a[1] / 0.7; //传送门用时
  32. for(int i=2; i<=n ; i++) {
  33. dp[i][0] = Math.min(dp[i-1][0]+x[i]-x[i-1], dp[i-1][1] + b[i-1]/1.3);
  34. dp[i][1] = Math.min(dp[i][0] + a[i] / 0.7, dp[i-1][1] + ((b[i-1]>a[i])?(b[i-1]-a[i])/1.3: (a[i]-b[i-1])/0.7));
  35. }
  36. pw.printf("%.2f",dp[n][0]);
  37. }
  38. }

 F、合并区域 (时间限制: 2.0s 内存限制: 512.0MB

【问题描述】
小蓝在玩一款种地游戏。现在他被分配给了两块大小均为 N × N 的正方形 区域。这两块区域都按照 N × N 的规格进行了均等划分,划分成了若干块面积 相同的小区域,其中每块小区域要么是岩石,要么就是土壤,在垂直或者水平 方向上相邻的土壤可以组成一块土地。现在小蓝想要对这两块区域沿着边缘进 行合并,他想知道合并以后可以得到的最大的一块土地的面积是多少(土地的 面积就是土地中土壤小区域的块数)? 在进行合并时,小区域之间必须对齐。可以在两块方形区域的任何一条边 上进行合并,可以对两块方形区域进行 90 度、 180 度、 270 度、 360 度的旋转, 但不可以进行上下或左右翻转,并且两块方形区域不可以发生重叠。
【输入格式】
第一行一个整数 N 表示区域大小。 接下来 N 行表示第一块区域,每行 N 个值为 0 1 的整数,相邻的整数 之间用空格进行分隔。值为 0 表示这块小区域是岩石,值为 1 表示这块小区域 是土壤。 再接下来 N 行表示第二块区域,每行 N 个值为 0 1 的整数,相邻的整 数之间用空格进行分隔。值为 0 表示这块小区域是岩石,值为 1 表示这块小区 域是土壤。
【输出格式】
一个整数表示将两块区域合并之后可以产生的最大的土地面积。
【样例输入】
  1. 4
  2. 0 1 1 0
  3. 1 0 1 1
  4. 1 0 1 0
  5. 1 1 1 0
  6. 0 0 1 0
  7. 0 1 1 0
  8. 1 0 0 0
  9. 1 1 1 1
【样例输出】
15
【样例说明】

第一张图展示了样例中的两块区域的布局。第二张图展示了其中一种最佳
的合并方式,此时最大的土地面积为 15
【评测用例规模与约定】
对于 30 % 的数据, 1 N 5
对于 60 % 的数据, 1 N 15
对于 100 % 的数据, 1 N 50

 Ⅰ、题目解读

题目会给你两块土地,你可以进行两块土地的“缝合”,求最大的连续的土地。
最大土地有三种情况
①、左右连接成一块最大的土地

②、单独一边中间是最大的土地

 

③、因为另一块土地的连接而导致原本不连接的土地也连接成新的土地(这种情况是我没想到的)

我只想到了前面两种情况,如果要算上第三种情况的话就应该直接使用暴力求解(毕竟数据量并不是很大),不断拼接,求最大连续的土地。我的代码也只是符合前面两种情况,有正确代码还请大佬给出。万分感谢。

 Ⅱ、代码

  1. import java.awt.*;
  2. import java.util.ArrayList;
  3. import java.util.HashSet;
  4. import java.util.List;
  5. import java.util.Scanner;
  6. public class Main {
  7. static class Point{
  8. int x,y;
  9. public Point(int x, int y) {
  10. this.x = x;
  11. this.y = y;
  12. }
  13. }
  14. public static void main(String[] args) {
  15. Scanner sc=new Scanner(System.in);
  16. int n=sc.nextInt();
  17. int[][] arr1=new int[n+2][n+2];//第一个矩阵
  18. int[][] arr2=new int[n+2][n+2];//第二个矩阵
  19. for (int i=1;i<=n;i++)
  20. for (int j=1;j<=n;j++){
  21. arr1[i][j]=sc.nextInt();
  22. }
  23. for (int i=1;i<=n;i++)
  24. for (int j=1;j<=n;j++){
  25. arr2[i][j]=sc.nextInt();
  26. }
  27. int max=0;
  28. for (int i=1;i<=n;i++)
  29. for (int j=1;j<=n;j++){
  30. if (arr1[i][j]==1){
  31. length(arr1,i,j);
  32. List<Point> list=new ArrayList<>(set);
  33. for (Point p:list)
  34. arr1[p.x][p.y]=sum;
  35. max=Math.max(max,sum);//防止矩阵里面是最大的
  36. sum=0;
  37. set.clear();
  38. }
  39. }
  40. for (int i=1;i<=n;i++)
  41. for (int j=1;j<=n;j++){
  42. if (arr2[i][j]==1){
  43. length(arr2,i,j);
  44. List<Point> list=new ArrayList<>(set);
  45. for (Point p:list)
  46. arr2[p.x][p.y]=sum;
  47. max=Math.max(max,sum);//防止矩阵里面是最大的
  48. sum=0;
  49. set.clear();
  50. }
  51. }
  52. int l=0;
  53. int r=0;
  54. //求四边的最大值然后拼接
  55. //两行
  56. for (int i=1;i<=n;i+=(n-1))
  57. for (int j=1;j<=n;j++){
  58. l=Math.max(l,arr1[i][j]);
  59. r=Math.max(r,arr2[i][j]);
  60. }
  61. //两列
  62. for (int i=1;i<=n;i++)
  63. for (int j=1;j<=n;j+=(n-1)){
  64. l=Math.max(l,arr1[i][j]);
  65. r=Math.max(r,arr2[i][j]);
  66. }
  67. max=Math.max(max,l+r);
  68. System.out.println(max);
  69. }
  70. static int sum=0;
  71. static HashSet<Point> set=new HashSet<>();
  72. public static void length(int[][] arr, int i, int j){
  73. sum++;
  74. arr[i][j]=0;
  75. Point p=new Point(i,j);
  76. set.add(p);
  77. if (arr[i-1][j]==1)
  78. length(arr,i-1,j);
  79. if (arr[i+1][j]==1)
  80. length(arr,i+1,j);
  81. if (arr[i][j-1]==1)
  82. length(arr,i,j-1);
  83. if (arr[i][j+1]==1)
  84. length(arr,i,j+1);
  85. }
  86. }

 G、买二赠一(时间限制: 1.0s 内存限制: 512.0MB)

【问题描述】
某商场有 N 件商品,其中第 i 件的价格是 A i 。现在该商场正在进行 买二 赠一” 的优惠活动,具体规则是: 每购买 2 件商品,假设其中较便宜的价格是 P (如果两件商品价格一样,
P 等于其中一件商品的价格),就可以从剩余商品中任选一件价格不超过 P /2 的商品,免费获得这一件商品。可以通过反复购买 2 件商品来获得多件免费商 品,但是每件商品只能被购买或免费获得一次。 小明想知道如果要拿下所有商品(包含购买和免费获得),至少要花费多少钱?
【输入格式】
第一行包含一个整数 N
第二行包含 N 个整数,代表 A 1 , A 2 , A 3 , . . . A N
【输出格式】
输出一个整数,代表答案。
【样例输入】
  1. 7
  2. 1 4 2 8 5 7 1

【样例输出】

25

【样例说明】

小明可以先购买价格 4 8 的商品,免费获得一件价格为 1 的商品;再后
买价格为 5 7 的商品,免费获得价格为 2 的商品;最后单独购买剩下的一件
价格为 1 的商品。总计花费 4 + 8 + 5 + 7 + 1 = 25 。不存在花费更低的方案。
【评测用例规模与约定】
对于 30 % 的数据, 1 N 20
对于 100 % 的数据, 1 N 5 × 10,1 A i ≤ 10

 Ⅰ、题目解读

要花费最少,就要购买的商品价格高点,这样可以白嫖到更贵的商品,而不是便宜的商品。如题目所给样例:7+8(2)+4+5(1)+1=25。我认为可以使用数组储存再sort排序,然后使用二分查找到符合小于p/2的最大值,再将已经买完的商品变为0(或者其他方法标记为已购买的状态),然后不断重复上面步骤。(博主使用word打开题目,题目有问题,p/2显示的是p2,看错题目了,纯纯大冤种

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/398791
推荐阅读
相关标签