A. 第几天
题目描述:
思路解析:
代码:
package 第9届;
/**
* @author: DreamCode
* @file: A_第几天.java
* @time: 2022年3月21日-下午9:54:37
* @答案:125
*/
public class A_第几天 {
static int[] arr= {31,29,31,30,31,30,31,31,30,31,30,31};
public static void main(String[] args) {
int ans = 0;
for(int i=0;i<4;i++) { //前4个月的天数
ans+=arr[i];
}
ans+=4;
System.out.println(ans);
}
}
B. 方格计数
题目描述:
思路解析:
代码:
package 第9届;
/**
* @author: DreamCode
* @file: B_方格计数.java
* @time: 2022年3月21日-下午9:58:38
* @答案: 3137548
*/
public class B_方格计数 {
public static void main(String[] args) {
int res=0;
int r=1000;
for(int x=1;x<=1000;x++) {
for(int y=1;y<=1000;y++) {
if(distance(x,y)<=r) {
res++;
}
}
}
System.out.println(res*4);
}
private static double distance(int x, int y) {
double d=Math.sqrt(x*x+y*y);
return d;
}
}
C. 复数幂
题目描述:
思路解析:
代码:
package 第9届;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.math.BigInteger;
/**
* @author: DreamCode
* @file: B_方格计数.java
* @time: 2022年3月21日-下午9:58:38
*/
public class C_复数幂 {
public static void main(String[] args) throws IOException {
BigInteger a = new BigInteger("2");
BigInteger b = new BigInteger("3");
for (int i = 0; i < 123455; i++) {
BigInteger c = a;
BigInteger d = b;
a = (new BigInteger("2").multiply(c)).subtract(new BigInteger("3").multiply(d));
b = (new BigInteger("2").multiply(d)).add(new BigInteger("3").multiply(c));
}
System.setOut(new PrintStream(new File("src/第9届/C_OutPut.txt")));
System.out.print(a);
if (b.compareTo(BigInteger.ZERO) > 0) {
System.out.print('+');
}
System.out.print(b);
System.out.print("i");
}
}
D. 测试次数
题目描述:
思路解析:
代码:
package 第9届;
/**
* @author: DreamCode
* @file: D_测试次数.java
* @time: 2022年3月21日-下午11:04:09 @答案:19
*/
public class D_测试次数 {
public static void main(String[] args) {
int n = 1000;
int k = 3;
int ans = DP(k, n);
System.out.println(ans);
}
private static int DP(int k, int n) {
int[][] dp = new int[k + 1][n + 1];
for (int i = 1; i <= n; i++) {
dp[1][i] = i; // 只有一部手机的时候,测试n层肯定是n次
}
for (int i = 2; i <= k; i++) { // 手机数从2-k
for (int j = 1; j <= n; j++) { // 测试层数从1-n
int strategy = Integer.MAX_VALUE; // 记录最佳策略结果
for (int p = 1; p <= j; p++) { // 测试j层有i部手机,模拟分别从1-j层开始摔,找最坏运气,最佳策略结果
int N = dp[i][j - p];// 当前层没摔坏,则需要用i部手机测试剩下的j-p层
int Y = dp[i - 1][p - 1];// 当前层摔坏了,则需要用i-1部手机测试剩下的p-1层
int bad_luck = 1 + Math.max(N, Y); // 最坏的运气
strategy = Math.min(strategy, bad_luck);// 最佳丢手机策略
}
dp[i][j] = strategy;
}
}
return dp[k][n];
}
}
E. 快速排序
代码填空题
package 第9届;
import java.util.Random;
/**
* @author: DreamCode
* @file: E_快速排序.java
* @time: 2022年3月21日-下午11:05:26
*/
public class E_快速排序 {
/**
* 以下代码可以从数组a[]中找出第k小的元素。
*
* 它使用了类似快速排序中的分治算法,期望时间复杂度是O(N)的。
*
* 请仔细阅读分析源码,填写划线部分缺失的内容。
*/
public static int quickSelect(int a[], int l, int r, int k) {
Random rand = new Random();
int p = rand.nextInt(r - l + 1) + l;
int x = a[p];
int tmp = a[p];
a[p] = a[r];
a[r] = tmp;
int i = l, j = r;
while (i < j) {
while (i < j && a[i] < x)
i++;
if (i < j) {
a[j] = a[i];
j--;
}
while (i < j && a[j] > x)
j--;
if (i < j) {
a[i] = a[j];
i++;
}
}
a[i] = x;
p = i;
if (i - l + 1 == k)
return a[i];
if (i - l + 1 < k)
return quickSelect(a,i+1,r,k-i+1); // 填空
else
return quickSelect(a, l, i - 1, k);
}
public static void main(String args[]) {
int[] a = { 1, 4, 2, 8, 5, 7 };
System.out.println(quickSelect(a, 0, 5, 4));
}
}
F. 递增三元组
题目描述:
思路解析:
package 第9届;
import java.util.Arrays;
import java.util.Scanner;
public class F_递增三元组{
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
int N=scanner.nextInt();
int[] A=new int[N];
int[] B=new int[N];
int[] C=new int[N];
for(int i=0;i<N;i++) {
A[i]=scanner.nextInt();
}
for(int i=0;i<N;i++) {
B[i]=scanner.nextInt();
}
for(int i=0;i<N;i++) {
C[i]=scanner.nextInt();
}
Arrays.sort(A);
Arrays.sort(B);
Arrays.sort(C);
long sum=0;
int p=0;
int q=0;
for(int i=0;i<N;i++) {
while(p<N&&A[p]<B[i]) {
p++;
}
while(q<N&&C[q]<=B[i]) {
q++;
}
sum+=(long)(p)*(N-q);
}
System.out.println(sum);
}
}
G. 螺旋折现
试题描述:
思路解析:
代码:
package 第9届;
import java.util.Scanner;
/**
* @author: DreamCode
* @file: G_螺旋折线.java
* @time: 2022年3月23日-下午8:16:00
*/
public class G_螺旋折线 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
long x = scanner.nextLong();
long y = scanner.nextLong();
long k = Math.max(Math.abs(x), Math.abs(y));
long sum = (8 + 8 * k) * k / 2;
long d = 0;// 计算与当前边长正方形左下角坐标的距离,并将sum减去距离值
if (y == k) { // 上边界
d = k - x + 4 * k;
} else if (x == k) {// 右边界
d = y - (-k) + 2 * k;
} else if (y == -k) {// 下边界
d = x - (-k);
} else if (x == -k) {// 左边界
d = k - y + 6 * k;
}
sum -= d;
System.out.println(sum);
}
}
H. 日志统计
题目描述:
思路解析:
代码:
package 第9届;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
import java.util.TreeSet;
/**
* @author: DreamCode
* @file: H_日志统计.java
* @time: 2022年3月23日-下午8:56:03
*/
public class H_日志统计 {
static class log {
public int ts;
public int td;
public log(int ts, int td) {
super();
this.ts = ts;
this.td = td;
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int N = scanner.nextInt();
int D = scanner.nextInt();
int K = scanner.nextInt();
log[] arr = new log[N];
for (int i = 0; i < N; i++) {
arr[i] = new log(scanner.nextInt(), scanner.nextInt());
}
Arrays.sort(arr, new Comparator<log>() { //指定排序规则
@Override
public int compare(log o1, log o2) {
if (o1.ts == o2.ts) {
return o1.td < o2.td ? -1 : 1;
}
return o1.ts < o2.ts ? -1 : 1;
}
});
solve(arr, D, K);
}
private static void solve(log[] arr, int D, int K) {
// TODO 尺取法解决问题
Map<Integer, Integer> rec = new HashMap<>(); // hash表记录每种id的点赞数
Set<Integer> ans = new TreeSet<>(); // 记录热帖的td,默认从小到大排序且去重
int p = 0, q = 0; // 尺取法的双指针
while (q < arr.length) { // 遍历每一种情况
while (arr[q].ts < arr[p].ts + D) {
q++;
if(q==arr.length) {
break;
}
}
for (int i = p; i < q; i++) { // 一次尺,尺子的长度满足[t,t+D);
if (rec.get(arr[i].td) == null) {
rec.put(arr[i].td, 1);
} else {
rec.put(arr[i].td, rec.get(arr[i].td) + 1);
}
}
for (Map.Entry<Integer, Integer> entry : rec.entrySet()) { // 查询当前的尺满足热帖要求的id
if (entry.getValue() >= K) {
ans.add(entry.getKey());
}
}
rec.clear(); //每一次尺取完以后将记录数组清空
p++;
}
Iterator<Integer> iterator=ans.iterator();
while(iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}
I. 全球变暖
题目描述:
思路解析:
代码:
package 第9届;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
/**
* @author: DreamCode
* @file: I_全球变暖.java
* @time: 2022年3月24日-下午10:58:21
*/
public class I_全球变暖 {
static class point {
public int x;
public int y;
public point(int x, int y) {
super();
this.x = x;
this.y = y;
}
}
static int[] x_stride = { -1, 1, 0, 0 }; // 分别代表上下左右移动
static int[] y_stride = { 0, 0, -1, 1 };
static boolean[][] vis; // 记录地图上的该点是否已访问
static char[][] map; // 记录地图上的元素
static int ans = 0; // 记录最终会被淹没的岛屿数量
static int n;
public static void main(String[] args) {
Scanner scanner = new Scanner(new BufferedInputStream(System.in));
n = scanner.nextInt();
map = new char[n][n];
vis = new boolean[n][n];
for (int i = 0; i < n; i++) {
map[i] = scanner.next().toCharArray();
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (map[i][j] == '#' && !vis[i][j]) { // 当前点未访问且当前点未 # ,以该点为中心进行BFS判断是否连通
BFS(i, j);
}
}
}
System.out.println(ans);
}
private static void BFS(int x, int y) {
// TODO BFS遍历
int cnt1 = 0; // 记录靠近海洋的陆地数量
int cnt2 = 0; // 记录陆地的数量
Queue<point> queue = new LinkedList<>(); // 构造队列存储每一个点
queue.offer(new point(x, y));
while (!queue.isEmpty()) {
cnt2++;
point p = queue.peek();
queue.remove();
vis[p.x][p.y] = true; // 标记该点已访问
boolean flag = false; // 默认当前陆地点不靠近海洋
for (int i = 0; i < 4; i++) {// 遍历四个方向
int next_x = p.x + x_stride[i];
int next_y = p.y + y_stride[i];
if (next_x >= 0 && next_x < n && next_y >= 0 && next_y < n) { // 边界判断
if (map[next_x][next_y] == '.') { // 当前的陆地点附近具有海洋,flag设为true
flag = true;
}
if (map[next_x][next_y] == '#' && !vis[next_x][next_y]) {// 附近点具有未访问的陆地,加入队列
queue.offer(new point(next_x, next_y));
}
}
}
if (flag) { // 当前的陆地点附近具有海洋
cnt1++;
}
}
if (cnt1 == cnt2) { // 当前岛屿的每一块陆地都靠海,会被淹没
ans++;
}
}
}
J. 堆的计数
题目描述:
思路解析:
代码:
package 第9届;
import java.util.Scanner;
/**
* @author: DreamCode
* @file: J_堆的计数.java
* @time: 2022-4-7-22:41:26
*/
public class J_堆的计数 {
private static final int MOD = 1000000009; //质数
private static int N;
private static int[] size; // 记录每个节点的size
private static long[] jie; // 记录1~N的阶乘
private static long[] ni; // 记录1~N的阶乘的逆元
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
N = sc.nextInt();
size = new int[N + 1];
jie = new long[N + 1];
ni = new long[N + 1];
initSize(); //预处理每一个节点的左右子树节点的个数
initJie(); //预处理阶层与数的逆元
System.out.println(dp());
sc.close();
}
private static long dp() { //动态规划递推
long[] d = new long[N + 1]; // d[i]表示的是i号节点作为根,小根堆的种数
for (int x = N; x >= 1; x--) {
if (2 * x + 1 <= N) {
d[x] = c(size[x] - 1, size[2 * x]) * d[2 * x] % MOD * d[2 * x + 1] % MOD;
} else if (2 * x <= N) {
d[x] = c(size[x] - 1, size[2 * x]) * d[2 * x] % MOD;
} else {
d[x] = 1;
}
}
return d[1];
}
private static void initJie() { //预处理阶乘与模的逆元
jie[0] = 1;
ni[0] = 1;
for (int i = 1; i <= N; i++) {
jie[i] = jie[i - 1] * i % MOD; //递推计算阶乘
ni[i] = qpow(jie[i], MOD - 2); //i的逆元为i!^(MOD-2)
}
}
private static long qpow(long a, int n) { //快速幂运算
if (a == 0) {
return 0;
}
long ans = 1;
long x = a;
while (n > 0) {
if ((n & 1) == 1) {
ans = ans * x % MOD;
}
n >>= 1;
x = x * x % MOD;
}
return ans;
}
private static void initSize() { //初始化每个节点左右子节点的数目。左节点的数目+右节点的数目+1
for (int i = N; i >= 1; i--) {
size[i] = (2 * i <= N ? size[2 * i] : 0) + (2 * i + 1 <= N ? size[2 * i + 1] : 0) + 1;
}
}
private static long c(int n, int r) { //求组合数:n!/r!/(n-r)!
return jie[n] * ni[r] % MOD * ni[n - r] % MOD;
}
}