纸张尺寸
原题链接
问题描述
解题思路
按照题意模拟即可,预处理出所有的答案。
参考代码
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();
}
}
最大数字
原题链接
问题描述
解题思路
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();
}
}
全排列的价值
原题链接
问题描述
解题思路
没写对,看了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();
}
}