赞
踩
目录
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)
H、合并石子(时间限制: 1.0s 内存限制: 512.0MB)
I、最大开支(时间限制: 1.0s 内存限制: 512.0MB )
J、魔法阵(时间限制: 1.0s 内存限制: 512.0MB )
2023年第十四届蓝桥杯JavaB组省赛文件已上传到csdn,可自行下载
蓝桥杯题目:2023年第十四届蓝桥杯大赛软件类省赛Java大学B组真题 - 题库 - C语言网 (dotcpp.com)
详细完整题解在这篇博客:
【问题描述】令 S = 1! + 2! + 3! + ... + 202320232023! ,求 S 的末尾 9 位数字。提示:答案首位不为 0 。
一看到三个2023的巨大数字,我想大家应该都人都麻了。但是我想说这是官方的骗术,因为题目说要求末尾的9位数,其实我想告诉大家当加到40多的阶乘时,这个阶乘和后面的9位数就不会发生改变了。
-
- public class Main {
- public static void main(String[] args) {
- long start=1;
- String s="202320232023";
- long end= Long.parseLong(s);
- long sum=0;
- long cj=1;
- while (start<=end){
- cj*=start;
- cj%=1000000000;
- sum+=cj;
- sum%=1000000000;
- start++;
- if (start>40)
- System.out.println(sum);
- }
- System.out.println(sum);
- }
- }
看运行
20940313 420940313 420940313 420940313 420940313 420940313 420940313 ...
这是因为40的阶乘之后后面 9位数都是0,所以阶乘之和末尾9位数不会再发生改变!
【问题描述】哈沙德数是指在某个固定的进位制当中,可以被各位数字之和整除的正整 数。例如 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 个幸运数 字是多少?你只需要告诉小蓝这个整数的十进制表示即可。
这题就是考察大家的进制转换,数据量也不大。直接看代码吧!
- public class {
- public static void main(String[] args) {
- int j=0;
- for (int i=1;i<10000000;i++){
- if (BaseConversion(i)){
- j++;
- if (j==2023){
- System.out.println(i);//215040
- break;
- }
- }
- }
- }
- public static boolean BaseConversion(int n){
- //十进制
- int sum=0;
- int x=n;
- while (x!=0){
- sum+=(x%10);
- x/=10;
- }
- if (n%sum!=0)
- return false;
- //二进制
- sum=0;
- x=n;
- while (x!=0){
- sum+=(x%2);
- x/=2;
- }
- if (n%sum!=0)
- return false;
- //八进制
- sum=0;
- x=n;
- while (x!=0){
- sum+=(x%8);
- x/=8;
- }
- if (n%sum!=0)
- return false;
- //十六进制
- int[] arr={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
- sum=0;
- x=n;
- while (x!=0){
- sum+=(arr[x%16]);
- x/=16;
- }
- if (n%sum!=0)
- return false;
- return true;
- }
- }
-
时间限制 : 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 进行取模后输出。【样例输入】
2 2 6 6 2 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情况
- //排列组合递推公式
-
- import java.util.Scanner;
- import java.math.BigInteger;
- public class Main {
- public static final BigInteger MOD = new BigInteger("1000000007");
- public static void main(String[] args) {
- Scanner scan = new Scanner(System.in);
- int T = scan.nextInt();
- while (T-- > 0){
- int n = scan.nextInt();
- int[] a = new int[n];
- long x = 0, y = 0; // x 记录偶数, y 记录奇数
- for(int i = 0; i < n; i++){
- a[i] = scan.nextInt() % 2;
- if(a[i] == 0){
- x++;
- }else {
- y++;
- }
- }
- if(y % 2 == 1){ // 奇数个数为奇,没有一个条件成立
- System.out.println(0);
- continue;
- }
- x = x + (y == 0 ? 0 : y - 1); // 两个奇数组合为一个偶数,排除重复情况
- BigInteger ans = new BigInteger("2");
- BigInteger dp = new BigInteger("1");
- // C(n,m) = P(n,m) / P(m,m) = n! / m! * (n - m)!
- // 转移递推公式 dp = (dp * (x, x-1, x-2, ... , n) / (1, 2, 3, ... , n))
- for(long i = 1, j = x; i < x; i++, j--){ // 排列组合无顺序 C
- BigInteger u = new BigInteger(String.valueOf(j));
- BigInteger v = new BigInteger(String.valueOf(i));
- dp = dp.multiply(u).divide(v);
- ans = ans.add(dp);
- }
- System.out.println(ans.mod(MOD));
- }
- }
- }
优化高精度
- import java.util.Scanner;
- import java.math.BigInteger;
- public class Main {
- public static final BigInteger MOD = new BigInteger("1000000007");
- public static final BigInteger TWO = new BigInteger("2");
- public static void main(String[] args) {
- Scanner scan = new Scanner(System.in);
- int T = scan.nextInt();
- while (T-- > 0) {
- int n = scan.nextInt();
- int x = 0, y = 0; // x 记录偶数, y 记录奇数
- for (int i = 0; i < n; i++) {
- int a = scan.nextInt() % 2;
- if (a == 0) {
- x++;
- } else {
- y++;
- }
- }
- if (y % 2 == 1) {
- System.out.println(0);
- }else{
- System.out.println(TWO.pow(x + (y == 0 ? 0 : y - 1)).mod(MOD));
- }
- }
- }
- }
【问题描述】平面上有个两个矩形 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))
- import java.util.Scanner;
-
- public class Main {
- public static void main(String[] args) {
- Scanner sc = new Scanner(System.in);
- int x1 = sc.nextInt();
- int y1 = sc.nextInt();
- int x2 = sc.nextInt();
- int y2 = sc.nextInt();
- int x3 = sc.nextInt();
- int y3 = sc.nextInt();
- int x4 = sc.nextInt();
- int y4 = sc.nextInt();
- long area1 = (long) (x2 - x1) * (y2 - y1); // 计算第一个矩形的面积
- long area2 = (long) (x4 - x3) * (y4 - y3); // 计算第二个矩形的面积
- long overlapArea=0;
- long l = Math.min(x2, x4) - Math.max(x1, x3);
- long w= Math.min(y2,y4)-Math.max(y1,y3);
- if (l >=0&&w >=0){
- overlapArea= l * w;
- }
- long Area = area1 + area2 - overlapArea; // 总面积
- System.out.println(Area); // 输出总面积
- }
- }
【问题描述】这天,一只蜗牛来到了二维坐标系的原点。 在 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 。【输出格式】输出共一行,一个浮点数表示答案( 四舍五入保留两位小数 )。【样例输入】
3 1 10 11 1 1 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 ≤ 10⁵ ,a i , b i ≤ 10⁴ ,x i ≤ 10⁹ 。
dp[i][j] 表示蜗牛走到第 i 根杆子的最短用时,j 表示状态。
j = 0 : 走到杆子底部
j = 1 :走到杆子的传送门处
P.S.由于只与前一个杆子状态有关,其实用两个变量就行,用二维数组便于理解
时间复杂度: O(n)
- import java.io.*;
- import java.util.*;
- public class Main{
- static int maxn = 200005,n,m;
- static long INF = (long)2e18,ans = 0,mod = (int)1e9+7;
- static Scanner sc = new Scanner (System.in);
- static BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
- static StreamTokenizer st =new StreamTokenizer(bf);
- static PrintWriter pw = new PrintWriter(new OutputStreamWriter(System.out));
- public static void main(String[]args) throws IOException{
- int T = 1;
- //T = Integer.parseInt(S());
- while(T-->0) solve();
- pw.flush();
- }
- static final int I() throws IOException {
- st.nextToken();
- return (int)st.nval;
- }
- static void solve() throws IOException{
- n = I();
- long x[] = new long [n+1];
- for(int i=1;i<=n;i++) x[i] = I();
- int []a = new int [n+1];
- int []b = new int [n+1];
- for(int i=1;i<n;i++) {
- a[i] = I();b[i] = I();
- }
- double dp[][] = new double[n+1][2];
- dp[1][0] = x[1]; //底端最小用时
- dp[1][1] = x[1] + a[1] / 0.7; //传送门用时
- for(int i=2; i<=n ; i++) {
- dp[i][0] = Math.min(dp[i-1][0]+x[i]-x[i-1], dp[i-1][1] + b[i-1]/1.3);
- 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));
- }
- pw.printf("%.2f",dp[n][0]);
- }
- }
【问题描述】小蓝在玩一款种地游戏。现在他被分配给了两块大小均为 N × N 的正方形 区域。这两块区域都按照 N × N 的规格进行了均等划分,划分成了若干块面积 相同的小区域,其中每块小区域要么是岩石,要么就是土壤,在垂直或者水平 方向上相邻的土壤可以组成一块土地。现在小蓝想要对这两块区域沿着边缘进 行合并,他想知道合并以后可以得到的最大的一块土地的面积是多少(土地的 面积就是土地中土壤小区域的块数)? 在进行合并时,小区域之间必须对齐。可以在两块方形区域的任何一条边 上进行合并,可以对两块方形区域进行 90 度、 180 度、 270 度、 360 度的旋转, 但不可以进行上下或左右翻转,并且两块方形区域不可以发生重叠。【输入格式】第一行一个整数 N 表示区域大小。 接下来 N 行表示第一块区域,每行 N 个值为 0 或 1 的整数,相邻的整数 之间用空格进行分隔。值为 0 表示这块小区域是岩石,值为 1 表示这块小区域 是土壤。 再接下来 N 行表示第二块区域,每行 N 个值为 0 或 1 的整数,相邻的整 数之间用空格进行分隔。值为 0 表示这块小区域是岩石,值为 1 表示这块小区 域是土壤。【输出格式】一个整数表示将两块区域合并之后可以产生的最大的土地面积。【样例输入】
4 0 1 1 0 1 0 1 1 1 0 1 0 1 1 1 0 0 0 1 0 0 1 1 0 1 0 0 0 1 1 1 1【样例输出】
15
【样例说明】
第一张图展示了样例中的两块区域的布局。第二张图展示了其中一种最佳的合并方式,此时最大的土地面积为 15 。【评测用例规模与约定】对于 30 % 的数据, 1 ≤ N ≤ 5 。对于 60 % 的数据, 1 ≤ N ≤ 15 。对于 100 % 的数据, 1 ≤ N ≤ 50 。
题目会给你两块土地,你可以进行两块土地的“缝合”,求最大的连续的土地。最大土地有三种情况①、左右连接成一块最大的土地![]()
②、单独一边中间是最大的土地
③、因为另一块土地的连接而导致原本不连接的土地也连接成新的土地(这种情况是我没想到的)
我只想到了前面两种情况,如果要算上第三种情况的话就应该直接使用暴力求解(毕竟数据量并不是很大),不断拼接,求最大连续的土地。我的代码也只是符合前面两种情况,有正确代码还请大佬给出。万分感谢。
-
- import java.awt.*;
- import java.util.ArrayList;
- import java.util.HashSet;
- import java.util.List;
- import java.util.Scanner;
-
- public class Main {
- static class Point{
- int x,y;
- public Point(int x, int y) {
- this.x = x;
- this.y = y;
- }
- }
- public static void main(String[] args) {
- Scanner sc=new Scanner(System.in);
- int n=sc.nextInt();
- int[][] arr1=new int[n+2][n+2];//第一个矩阵
- int[][] arr2=new int[n+2][n+2];//第二个矩阵
- for (int i=1;i<=n;i++)
- for (int j=1;j<=n;j++){
- arr1[i][j]=sc.nextInt();
- }
- for (int i=1;i<=n;i++)
- for (int j=1;j<=n;j++){
- arr2[i][j]=sc.nextInt();
- }
- int max=0;
- for (int i=1;i<=n;i++)
- for (int j=1;j<=n;j++){
- if (arr1[i][j]==1){
- length(arr1,i,j);
- List<Point> list=new ArrayList<>(set);
- for (Point p:list)
- arr1[p.x][p.y]=sum;
- max=Math.max(max,sum);//防止矩阵里面是最大的
- sum=0;
- set.clear();
- }
- }
- for (int i=1;i<=n;i++)
- for (int j=1;j<=n;j++){
- if (arr2[i][j]==1){
- length(arr2,i,j);
- List<Point> list=new ArrayList<>(set);
- for (Point p:list)
- arr2[p.x][p.y]=sum;
- max=Math.max(max,sum);//防止矩阵里面是最大的
- sum=0;
- set.clear();
- }
- }
- int l=0;
- int r=0;
- //求四边的最大值然后拼接
- //两行
- for (int i=1;i<=n;i+=(n-1))
- for (int j=1;j<=n;j++){
- l=Math.max(l,arr1[i][j]);
- r=Math.max(r,arr2[i][j]);
- }
- //两列
- for (int i=1;i<=n;i++)
- for (int j=1;j<=n;j+=(n-1)){
- l=Math.max(l,arr1[i][j]);
- r=Math.max(r,arr2[i][j]);
- }
- max=Math.max(max,l+r);
- System.out.println(max);
- }
- static int sum=0;
- static HashSet<Point> set=new HashSet<>();
- public static void length(int[][] arr, int i, int j){
- sum++;
- arr[i][j]=0;
- Point p=new Point(i,j);
- set.add(p);
- if (arr[i-1][j]==1)
- length(arr,i-1,j);
- if (arr[i+1][j]==1)
- length(arr,i+1,j);
- if (arr[i][j-1]==1)
- length(arr,i,j-1);
- if (arr[i][j+1]==1)
- length(arr,i,j+1);
- }
- }
【问题描述】某商场有 N 件商品,其中第 i 件的价格是 A i 。现在该商场正在进行 “ 买二 赠一” 的优惠活动,具体规则是: 每购买 2 件商品,假设其中较便宜的价格是 P (如果两件商品价格一样,则 P 等于其中一件商品的价格),就可以从剩余商品中任选一件价格不超过 P /2 的商品,免费获得这一件商品。可以通过反复购买 2 件商品来获得多件免费商 品,但是每件商品只能被购买或免费获得一次。 小明想知道如果要拿下所有商品(包含购买和免费获得),至少要花费多少钱?【输入格式】第一行包含一个整数 N 。第二行包含 N 个整数,代表 A 1 , A 2 , A 3 , . . . , A N【输出格式】输出一个整数,代表答案。【样例输入】
7 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
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。