[补题记录] Atcoder Beginner Contest 323(E、F)

URL:https://atcoder.jp/contests/abc323

目录

E

Problem/题意

Thought/思路

Code/代码

F

Problem/题意

Thought/思路

Code/代码


E

Problem/题意

有 N 首歌曲,每首歌曲时长为 Ti。每次随机播放一首歌曲,问在 X + 0.5 这一时刻,播放第一首歌的概率是多少。

Thought/思路

如果我们能求出从 X - T[1] + 1 到 X 的每一时刻开始时,恰好播放完上一首歌的概率,那么就可以将这 T[1] 个时刻加起来,再除以 N,就是从 X 开始,播放第一首歌的概率。

因此,dp[i] 表示,第 i 秒开始时,上一首歌结束,下一首歌准备开始播放的概率。

当 i > T[j] 时,就可以把当前第 j 首歌播放的概率累加到 dp[i] 上。

Code/代码

cpp 复制代码
#include "bits/stdc++.h"

#define int long long

const int mod = 998244353;

int n, x, t[10007], dp[10007];

int ksm(int a, int b) {
	int res = 1;
	while (b > 0) {
		if (b & 1) res = res * a % mod;
		a = a * a % mod;
		b >>= 1;
	}
	return res;
}

signed main() {
	std::cin >> n >> x;
	for (int i = 1; i <= n; ++ i) std::cin >> t[i];

	dp[0] = 1;
	for (int i = 1; i <= x; ++ i) {
		int cnt = 0;
		for (int j = 1; j <= n; ++ j) {
			if (i >= t[j]) {
				cnt ++;
				dp[i] = (dp[i] + ksm(n, mod - 2) * dp[i - t[j]] % mod) % mod;
			}
		}
	}

	int s = (x - t[1] + 1 < 0 ? 0 : x - t[1] + 1); // 从 s 开始放
	int ans = 0;
	for (int i = s; i <= x; ++ i) {
		ans = (ans + dp[i]) % mod;
	}
	ans = ans * ksm(n, mod - 2) % mod;

	std::cout << ans;
}

F

Problem/题意

给出三个点的坐标,点 A 表示人、点 B 表示一个箱子、点 C 表示目标点,现在要将箱子推到目标点:

  • 可以将箱子向上、下、左、右推,但人和箱子必须同一朝向且人在箱子之后;
  • 每走一格代价 + 1;
  • 问最小的代价是多少;

Thought/思路

From:https://zhuanlan.zhihu.com/p/660042738

对于第二句话,我们可以将目标点 C 都换到上半轴,那么 A 只需要移动到 (0, -1)、(-1, 0)、(1, 0) 即可去到推箱子的最佳位置。

详见代码。

Code/代码

cpp 复制代码
#include "bits/stdc++.h"

#define int long long

struct node {
	int x, y;
	node operator - (const node &t) const {
		return node({x - t.x, y - t.y});
	}
}a, b, c;

void reverseAC() {
	c.x = -c.x;
	c.y = -c.y;
	a.x = -a.x;
	a.y = -a.y;
}

signed main() {
	std::cin >> a.x >> a.y;
	std::cin >> b.x >> b.y;
	std::cin >> c.x >> c.y;

	// 以 b 为中心
	a.x -= b.x;
	a.y -= b.y;
	c.x -= b.x;
	c.y -= b.y;
	b.x = b.y = 0;

	int ans = std::abs(c.x) + std::abs(c.y); // 先算 B 到 C 的代价

	if (c.x < 0 and c.y < 0) { // 将 C 偏移到右上方
		reverseAC();
	}
	if (c.x > 0 and c.y > 0) { // A 移动到 -1, 0 或 0, -1
		node p1 = a - node({-1, 0}), p2 = a - node({0, -1});
		// +2 是因为移动箱子时,需要换方向
		ans += std::min(std::abs(p1.x) + std::abs(p1.y), std::abs(p2.x) + std::abs(p2.y)) + 2;
		std::cout << ans;
		return 0;
	}

	if (c.x > 0 and c.y < 0) {
		reverseAC();
	}
	if (c.x < 0 and c.y > 0) {
		node p1 = a - node({1, 0}), p2 = a - node({0, -1});
		ans += std::min(std::abs(p1.x) + std::abs(p1.y), std::abs(p2.x) + std::abs(p2.y)) + 2;
		std::cout << ans;
		return 0;
	}

	if (c.x == 0) { // C 在轴上
		if (c.y < 0) { // 将 C 偏移到正半轴
			reverseAC();
		}
		if (a.x == 0 and a.y > 0) { // A 也在正半轴上,需要绕回负半轴
			ans += 2;
		}
		node p = a - node({0, -1});
		ans += std::abs(p.x) + std::abs(p.y);
		std::cout << ans;
		return 0;
	}
	if (c.y == 0) {
		if (c.x < 0) {
			reverseAC();
		}
		if (a.y == 0 and a.x > 0) {
			ans += 2;
		}
		node p = a - node({-1, 0});
		ans += std::abs(p.x) + std::abs(p.y);
		std::cout << ans;
		return 0;
	}
}
相关推荐
penguin_bark1 分钟前
69. x 的平方根
算法
这可就有点麻烦了11 分钟前
强化学习笔记之【TD3算法】
linux·笔记·算法·机器学习
苏宸啊17 分钟前
顺序表及其代码实现
数据结构·算法
lin zaixi()20 分钟前
贪心思想之——最大子段和问题
数据结构·算法
FindYou.21 分钟前
C - Separated Lunch
算法·深度优先
夜雨翦春韭26 分钟前
【代码随想录Day30】贪心算法Part04
java·数据结构·算法·leetcode·贪心算法
Kent_J_Truman38 分钟前
【平方差 / C】
算法
一直学习永不止步39 分钟前
LeetCode题练习与总结:H 指数--274
java·数据结构·算法·leetcode·数组·排序·计数排序
Amor风信子1 小时前
华为OD机试真题---跳房子II
java·数据结构·算法
戊子仲秋1 小时前
【LeetCode】每日一题 2024_10_2 准时到达的列车最小时速(二分答案)
算法·leetcode·职场和发展