第十四届蓝桥杯三月真题刷题训练——第 20 天

纸张尺寸

原题链接

纸张尺寸

问题描述

todo:这里复制题目描述

解题思路

按照题意模拟即可,预处理出所有的答案。

参考代码

import java.io.*;

public class Main {

    static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
    static PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
    
    static int a = 1189, b = 841;
    static int[][] arr = new int[10][2];
    static {
    	arr[0][0] = a;
    	arr[0][1] = b;
    	for (int i = 1; i <= 9; i++) {
    		arr[i][0] = arr[i - 1][1];
    		arr[i][1] = arr[i - 1][0] / 2;
    	}
    }
    
    public static void main(String[] args) throws Exception {
    	String s = in.readLine();
    	int idx = s.charAt(1) - '0';
    	out.println(arr[idx][0]);
    	out.println(arr[idx][1]);

        out.flush();
        in.close();
    }  
}

最大数字

原题链接

最大数字

问题描述

todo:这里复制题目描述

解题思路

dfs,对于操作2来说,需要满足一定的条件才可以使用,否则会产生负收益,条件一则不受影响。

参考代码

import java.util.*;
import java.math.*;
import java.io.*;

public class Main {

    static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
    // static StreamTokenizer st = new StreamTokenizer(in);
    static PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
    
    static int a, b, n;
    static char[] num;
    static long ans = 0L;
    
    public static void dfs(int cur, long number) {
    	if (cur == n) {
    		ans = Math.max(ans, number);
    		return;
    	}
    	int t1 = Math.min(a, '9' - num[cur]);
    	a -= t1;
    	dfs(cur + 1, number * 10 + num[cur] - '0' + t1);
    	a += t1;
    	if (num[cur] - '0' + 1 <= b) {
    		b = b - (num[cur] - '0' + 1);
    		dfs(cur + 1, number * 10 + 9);
    		b = b + (num[cur] - '0' + 1);
    	}
    	
    }
    
    public static void main(String[] args) throws Exception {
    	String[] s = in.readLine().split(" ");
    	a = Integer.parseInt(s[1]);
    	b = Integer.parseInt(s[2]);
    	
    	num = s[0].toCharArray();
    	n = num.length;
    	dfs(0, 0);
    	
    	out.println(ans);

        out.flush();
        in.close();
    }  
}

全排列的价值

原题链接

全排列的价值

问题描述

todo:这里复制题目描述

解题思路

没写对,看了lh哥哥的题解秒懂!lh哥哥题解链接。具体都在代码注释里了。

参考代码

import java.io.*;

public class Main {

    static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
    static PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
   
    static int N = (int)1e6 + 10, MOD = 998244353, n;
    static long[] f = new long[N], g = new long[N];
    
    public static void main(String[] args) throws Exception {
    	n = Integer.parseInt(in.readLine());
    	// f[i] 前 n 个数的价值
    	f[2] = 1;
    	// g[i] 前 i 个数的排列总数
    	g[2] = 2;
    	/*  f[2]		f[3]
			(1,2):1	 ->	(1,2,3):1 + 2
				        (1,3,2):1 + 1
						(3,1,2):1 + 0
						
			(2,1):0	 ->	(2,1,3):0 + 2
						(2,3,1):0 + 1
						(3,2,1):0 + 0
    	 */
    	for (int i = 3; i <= n; i++) {
    		// f[i]: 前边的所有的排列的价值翻 i 倍 + 第 i 个数贡献的价值
    		f[i] = (f[i - 1] * i % MOD + (long)(i - 1) * i / 2 % MOD * g[i - 1] % MOD) % MOD;
    		g[i] = g[i - 1] * i % MOD;
    	}
    	
    	out.println(f[n]);

        out.flush();
        in.close();
    }  
}

修路

原题链接

修路

问题描述

在这里插入图片描述

解题思路

动态规划,没有思路!看了lh哥哥的题解豁然开朗,瞬间ac,lh哥哥题解链接

参考代码

import java.util.*;
import static java.lang.Math.*;
import java.io.*;

public class Main {

    static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
    // static StreamTokenizer st = new StreamTokenizer(in);
    static PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
    
    static int N = 2010, n, m, d, INF = 0x3f3f3f3f;
    static double[][][] f = new double[N][N][2];
    static int[] roadA = new int[N], roadB = new int[N];
    
    public static double dis(double d, long rA, long rB) {
    	return sqrt((rA - rB) * (rA - rB) + d * d);
    }
    
    public static void main(String[] args) throws Exception {
    	String[] s = in.readLine().split(" ");
    	n = Integer.parseInt(s[0]);
    	m = Integer.parseInt(s[1]);
    	d = Integer.parseInt(s[2]);
    	s = in.readLine().split(" ");
    	for (int i = 1; i <= n; i++) roadA[i] = Integer.parseInt(s[i - 1]);
    	s = in.readLine().split(" ");
    	for (int i = 1; i <= m; i++) roadB[i] = Integer.parseInt(s[i - 1]);
    	
    	Arrays.sort(roadA, 1, n + 1);
    	Arrays.sort(roadB, 1, m + 1);
    	
    	/*
    	 1. dp 数组下标定义
    	 f[i][j][0]: 当前道路A维修了i个点,道路B维修了j个点,并且当前在道路A时的最短距离
    	 f[i][j][1]: 当前道路A维修了i个点,道路B维修了j个点,并且当前在道路B时的最短距离
    	
    	 2. dp 数组初始化
    	 f[i][0][0] = roadA[i]: 表示道路A维修了i个点,并且当前在道路A时的最短距离
    	 f[i][0][1] = INF: 没什么卵用的情况
    	 f[0][j][0] = INF: 同上
    	 f[0][j][1] = startToB + roadB[j] - roadB[1]: 其中startToB为起点到道路B的第一个维修点的距离
    	
    	 3. 状态转移 => 记清楚下标含义即可得出转移方程
    	 f[i][j][0] = min(f[i - 1][j][0] + roadA[i] - roadA[i - 1], f[i - 1][j][1] + dis(d, roadA[i], roadB[j]))
    	 f[i][j][1] = min(f[i][j - 1][1] + roadB[j] - roadB[j - 1], f[i][j - 1][0] + dis(d, roadA[i], roadB[j]))
    	
    	 4. 最终答案
    	 min(f[n][m][0], f[n][m][1])
 
    	 */
    	
    	// 起点到道路B的第一个维修点的距离
    	double startToB = dis(d, roadB[1], 0);
    	
    	// 初始化
    	for (int i = 1; i <= n; i++) {
    		f[i][0][0] = roadA[i];
    		f[i][0][1] = INF;
    	}
    	for (int j = 1; j <= m; j++) {
    		f[0][j][0] = INF;
    		f[0][j][1] = startToB + roadB[j] - roadB[1];
    	}
    	
    	for (int i = 1; i <= n; i++) {
    		for (int j = 1; j <= m; j++) {
    			f[i][j][0] = min(f[i - 1][j][0] + roadA[i] - roadA[i - 1], f[i - 1][j][1] + dis(d, roadA[i], roadB[j]));
    			f[i][j][1] = min(f[i][j - 1][1] + roadB[j] - roadB[j - 1], f[i][j - 1][0] + dis(d, roadA[i], roadB[j]));
    		}
    	}
    	
    	out.printf("%.2f", min(f[n][m][0], f[n][m][1]));

        out.flush();
        in.close();
    }  
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值