76
突破口在于如果当前卡片的数量小于0,则输出当前卡片表示的数的前一个数。若当前卡片足以表示一个数时,更新答案。
3181
import java.util.Arrays; /** * @Description * @Author:PrinceHan * @CreateTime:2022/2/22 19:11 */ public class Main { public static void main(String[] args) { int[] nums = new int[10]; int ans = -1; Arrays.fill(nums, 2021); for (int i = 0; i < 10000; i++) { int tmp = i; if (tmp == 0) nums[0]--; else { while (tmp != 0) { if (nums[tmp % 10] < 0) { System.out.println(ans - 1); System.exit(0); } nums[tmp % 10]--; tmp /= 10; } } ans = i; } } }
不同的直线斜率或者截距必有一个不同,使用字符串来表示每条直线的斜率和截距,并存入集合当中。
40257
import java.util.ArrayList; import java.util.HashSet; /** * @Description * @Author:PrinceHan * @CreateTime:2022/2/22 19:44 */ public class C { static class Point { int x, y; Point(int x, int y) { this.x = x; this.y = y; } } public static void main(String[] args) { ArrayList<Point> points = new ArrayList<>(); HashSet<String> lines = new HashSet<>(); int m = 19; int n = 20; int ans = 0; for (int i = 0; i <= 19; i++) { for (int j = 0; j <= 20; j++) { points.add(new Point(i, j)); } } for (int i = 0; i < points.size(); i++) { for (int j = 0; j < points.size(); j++) { int x1 = points.get(i).x, y1 = points.get(i).y; int x2 = points.get(j).x, y2 = points.get(j).y; if (x1 == x2 && y1 == y2) continue; if (x1 == x2) { lines.add("x =" + x1);//考虑斜率不存在时的情况 } else if (y1 == y2) { lines.add("y =" + y1); } else { int dx = x2 - x1; int dy = y2 - y1; int gcd1 = gcd(dx, dy); int gcd2 = gcd(y1 * dx - x1 * dy, dx); lines.add("k = " + dy / gcd1 + "/" + dx / gcd1 + " d = " + (y1 * dx - x1 * dy) / gcd2 + "/" + dx / gcd2);//化简斜率和截距 } } } for (String e : lines) { System.out.println(e); } System.out.println(lines.size()); } static int gcd(int m, int n) { return m % n == 0 ? n : gcd(n, m % n); } }
首先保存一下2021041820210418的所有因数,只需遍历到该数的平方根为止,可以运行的更快。这个题可以用全排列的方法来做,选择三个因数进行全排列。
2430
import java.util.ArrayList; import java.util.stream.Collectors; /** * @Description * @Author:PrinceHan * @CreateTime:2022/2/22 20:24 */ public class D { static int ans; static long n = 2021041820210418l; static long[] nums = new long[10]; static ArrayList<Long> longs = new ArrayList<>(); public static void main(String[] args) { for (long i = 1; i * i <= n; i++) { if (n % i == 0) { longs.add(i); longs.add(n / i); } } longs = (ArrayList<Long>) longs.stream().distinct().collect(Collectors.toList());//去重 dfs(0, 1); System.out.println(ans); } static void dfs(int a, long now) { if (a == 3) { if (now == n) { ans++; } return; } for (int i = 0; i < longs.size(); i++) { nums[a] = longs.get(i); dfs(a + 1, now * longs.get(i)); nums[a] = 0; } } }
首先初始化一个边集数组,初始化数组元素足够大Integer.MAX_VALUE
,接着根据要求来给各顶点连边,并用路径场长度更新边集数组,最后用Floyd算法计算最短路径。
10266837
import java.util.Arrays; /** * @Description * @Author:PrinceHan * @CreateTime:2022/2/23 18:03 */ public class E { static long[][] edge = new long[2100][2100]; public static void main(String[] args) { for (int i = 1; i <= 2021; i++) { Arrays.fill(edge[i], Integer.MAX_VALUE);//初始化 } for (int i = 1; i <= 2021; i++) { for (int j = i + 1; j <= i + 21 && j <= 2021; j++) { int gcd = gcd(i, j); edge[i][j] = i * j / gcd;//最小公倍数 edge[j][i] = edge[i][j]; } } for (int i = 1; i <= 2021; i++) { for (int j = 1; j <= 2021; j++) { for (int k = 1; k <= 2021; k++) { if (edge[j][k] > edge[j][i] + edge[i][k]) edge[j][k] = edge[j][i] + edge[i][k]; } } } System.out.println(edge[1][2021]); } static int gcd(int m, int n) { return m % n == 0 ? n : gcd(n, m % n); } }
import java.util.Scanner; /** * @Description * @Author:PrinceHan * @CreateTime:2022/2/23 20:45 */ public class F { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); long l = scanner.nextLong(); l /= 1000; l %= 86400; long h = l / 3600; l %= 3600; long m = l / 60; long s = l % 60; System.out.printf("%02d:%02d:%02d", h, m, s); } }
一开始想着暴力解,结果超时了,这里参考了大雪菜的思路,第十二届蓝桥杯C++ B组讲解,思路比较新颖。
import java.util.Scanner; /** * @Description * @Author:PrinceHan * @CreateTime:2022/2/23 22:21 */ public class H { static long n; public static void main(String[] args) { Scanner scanner = new Scanner(System.in); n = scanner.nextLong(); for (int k = 16; ; k--) { if (check(k)) break; } } //求组合数 static long c(int a, int b) { long res = 1; for (int i = a, j = 1; j <= b; i--, j++) { res = res * i / j; if (res > n) return res; } return res; } //二分检查 static boolean check(int k) { int l = 2 * k, r = (int) Math.max(n, l); while (l < r) { int mid = (l + r) / 2; if (c(mid, k) >= n) r = mid; else l = mid + 1; } if (c(r, k) != n) return false; // C(r, k)的从0开始的顺序! int loc = (r + 1) * r / 2 + k + 1; System.out.println(loc); return true; } }