[补题记录] 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;
	}
}
相关推荐
挺菜的5 分钟前
【算法刷题记录(简单题)003】统计大写字母个数(java代码实现)
java·数据结构·算法
mit6.8245 分钟前
7.6 优先队列| dijkstra | hash | rust
算法
2401_8582861138 分钟前
125.【C语言】数据结构之归并排序递归解法
c语言·开发语言·数据结构·算法·排序算法·归并排序
guygg881 小时前
基于matlab的FIR滤波器
开发语言·算法·matlab
ysh98882 小时前
PP-OCR:一款实用的超轻量级OCR系统
算法
遇雪长安2 小时前
差分定位技术:原理、分类与应用场景
算法·分类·数据挖掘·rtk·差分定位
数通Dinner2 小时前
RSTP 拓扑收敛机制
网络·网络协议·tcp/ip·算法·信息与通信
张人玉4 小时前
C# 常量与变量
java·算法·c#
weixin_446122465 小时前
LinkedList剖析
算法
百年孤独_6 小时前
LeetCode 算法题解:链表与二叉树相关问题 打打卡
算法·leetcode·链表