【算法练习】Acwing第42周周赛

本文分享了算法练习中的三个难题:最小值计算通过迭代优化,动态规划解决字符串出现次数问题,以及利用二叉树特性求解满二叉树等长路径。理解并实现这些概念有助于提升编程技能和数据结构知识。


又又卡在了最后一题…(第二题卡了太多时间了,第二题的感觉就是很熟悉,但是又不知道哪里熟悉,搞半天没做出来,最后想了个简单方法)

一、最小值(简单)

就是打卡的

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

public class Main {
	static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
	static BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out));
	public static void main(String[] args) throws IOException {
//		String[] str = in.readLine().trim().split(" ");
		Scanner scan = new Scanner(System.in);
		int n = scan.nextInt();
		int m = scan.nextInt();
		int a = scan.nextInt();
		int b = scan.nextInt();
		double min = 1.0 * a / b;
		for (int i = 1; i < n; ++i) {
			a = scan.nextInt();
			b = scan.nextInt();
			min = Math.min(min, 1.0 * a / b);
		}
		System.out.printf("%.6f", m * min);
	}
}

二、出现次数(中等)

在这里插入图片描述

在这里插入图片描述

就是这道题…一看就有动态规划那味,但是该怎么避免重复计算呢?我的方法是:
我只用遍历一次字符串a,统计以当前字符开头,能否能够构成字符串b(必须要包含当前字符),如果可以,那就是这个下标能够贡献1个b子串数目,统计完a的下标后,就可以根据左右l r来进行查询值了。

给出l、r值,我们只要累加这个区间内的贡献值即可,然是要注意 l 是开始下标,r 是结束下标,我们的贡献值是以开始节点来算的,所以我们不能累加到cnt[r],而是cnt[r - bLen]!!

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

public class Main {
	static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
	static BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out));
	public static void main(String[] args) throws IOException {
		String[] strr = in.readLine().trim().split(" ");
		int n = Integer.parseInt(strr[0]);
		int m = Integer.parseInt(strr[1]);
		int q = Integer.parseInt(strr[2]);
		String a = in.readLine().trim();
		String b = in.readLine().trim();
		int[] cnt = new int[n];
		for (int i = 0; i < n; i++) {
			String str = a.substring(i, n);
			if (str.indexOf(b) == 0) cnt[i] = 1;
		}
		while (q-- > 0) {
			strr = in.readLine().trim().split(" ");
			int l = Integer.parseInt(strr[0]);
			int r = Integer.parseInt(strr[1]);
			int ans = 0;
			// r作为结束下标,那它的开始下标:r - m
			for (int i = l - 1; i <= r - m; i++) {
				ans += cnt[i];
			}
			out.write(ans + "\n");
		}
		out.flush();
	}
}

三、满二叉树等长路径(困难)

在这里插入图片描述

在这里插入图片描述
这道题是这周周赛最漂亮的一题,很考验对二叉树性质的掌握,代码很简单,但就看能不能想到。在读入路径长度时,顺便记录从根节点到叶子节点的长度,之后从叶子节点开始遍历,每次遍历两个叶子节点,记录根节点到它们之间距离的差值的绝对值,并把根节点的值更新为它们中的最大值,然后重复上面的操作,直到到达根节点,这个过程可以画图手推,很容易就发现规律了。

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

public class Main {
	public static void main(String[] args) {
		Scanner scan = new Scanner(System.in);
		int n = scan.nextInt();
		n = (int)Math.pow(2, n + 1) - 1;
		int[] len = new int[n + 1];
		// 把边信息存在点上!
		for (int i = 2; i <= n; i++) {
			// 顺便求根节点到每个节点的距离
			len[i] = scan.nextInt() + len[i / 2];
		}
		int ans = 0;
		// 到根节点就不遍历了
		for (int i = n; i >= 2; i -= 2) {
			// 记录相邻节点的差值的绝对值
			ans += Math.abs(len[i] - len[i - 1]);
			// 更新根节点为两者的最大值
			len[i / 2] = Math.max(len[i], len[i - 1]);
		}
		System.out.println(ans);
	}
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@u@

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值