大家好,我是snippet,今天是刷蓝桥真题的第二十二天,今天的后面三个题之前都写过几次,虽然还不是很熟练,但是思路还是清晰的,今天的知识点包含dfs+前缀和+二分,下面是我今天的题解
目录
一、受伤的皇后
题目链接:受伤的皇后 - 蓝桥云课 (lanqiao.cn)
题目内容:
解题思路:
代码:
package 蓝桥杯31天真题冲刺.Day22;
import java.util.Scanner;
/**
* @author snipprt
* @data 2023-03-25
* 受伤的皇后-蓝桥云课
*/
public class T1_受伤的皇后 {
static int[][] arr;
static int[] col;
static int ans = 0, n;
static void dfs(int i) {
if (i == n) {
ans++;
return;
}
// 遍历第i行的每一列
for (int j = 0; j < n; j++) {
if (check(i, j)) {
col[i] = j;
dfs(i+1);
}
}
}
static boolean check(int r, int c) {
for (int i = 0; i < r; i++) {
if (col[i] == c || (Math.abs(r - i) == Math.abs(c - col[i]) && (r - i) < 3)) return false;
}
return true;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
arr = new int[n][n];
col = new int[n];
dfs(0);
System.out.println(ans);
}
}
二、完全平方数
题目链接:完全平方数 - 蓝桥云课 (lanqiao.cn)
题目内容:
解题思路:
代码:
package 蓝桥杯31天真题冲刺.Day22;
import java.util.Scanner;
/**
* @author snipprt
* @data 2023-03-25
* 完全平方数-蓝桥云课
*/
public class T2_完全平方数 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
long n = sc.nextLong();
for (long i = 2; i*i <= n; i++) {
while (n % (i * i) == 0) {
n /= i*i;
}
}
System.out.println(n);
}
}
三、123
题目内容:
解题思路:
代码:
package 蓝桥杯31天真题冲刺.Day22;
import java.io.*;
/**
* @author snipprt
* @data 2023-03-25
* 123-蓝桥云课
*/
// 前缀和+二分
public class T3_123 {
static long[] s = new long[1500010];
public static void main(String[] args) throws IOException {
StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
long t = 0;
// 预处理得到s[i]表示i个区间的和
for (int i = 1; i <= 1500000; i++) {
t += i;
s[i] = s[i-1] + t;
}
in.nextToken();
int n = (int) in.nval;
while (n-- > 0) {
in.nextToken();
long a = (long)in.nval;
in.nextToken();
long b = (long)in.nval;
out.println(slove(b) - slove(a-1));
out.flush();
}
}
// 求前x个元素的前缀和
public static long slove(long x) {
int left = 1, right = 1500000;
while (left < right) {
// 二分快速求得 x 位于 sum 中的哪一块位置
int mid = left + right >> 1;
if (f(mid) < x) {
left = mid + 1;
} else {
right = mid;
}
}
// 求前面的块
right--;
// 求当前块的位置
x -= f(right);
// 用前面块的和 + 当前块位置的前缀和
return s[right] + f(x);
}
public static long f(long x) {
// 等差数列求和
return (1L + x) * x / 2;
}
}
四、求阶乘
题目内容:
解题思路:
代码:
package 蓝桥杯31天真题冲刺.Day22;
import java.util.Scanner;
/**
* @author snipprt
* @data 2023-03-25
* 求阶乘-蓝桥云课
*/
// 二分
public class T4_求阶乘 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
long k = sc.nextLong();
long l = 1;
long r = (long) 9e18;
while (l < r) {
long mid = l + (r - l) / 2;
if (check(mid) < k) {
l = mid + 1;
} else {
r = mid;
}
}
System.out.println(check(r) == k ? r : -1);
}
static long check(long x) {
long ans = 0;
while (x > 0) {
ans += x / 5;
x /= 5;
}
return ans;
}
}