1 条题解
-
0
题目理解
我们有一个矩形区域,左下角是 ,右上角是 ,需要从起点 走到终点 。
矩形内有一些 水平激光:第 条水平激光在 上,从 到 。
还有一些 垂直激光:第 条垂直激光在 上,从 到 。我们从起点到终点的路径必须是连续的曲线,可以任意方向走,但每穿过一次激光线就计一次穿越。
如果经过某条水平激光和某条垂直激光的交点,那么因为同时穿过它们,算 两次 穿越。题目要求 最少的穿越次数。
关键观察
-
起点与终点
起点 和终点 都在矩形的两个对角,且它们都不在激光上(因为水平激光的 ,垂直激光的 )。 -
激光的阻挡作用
如果我们想从 到 ,必须“跨过”这些激光。
在一个方向(例如水平方向)上,如果我们沿着一条 常数的线水平穿过,就会垂直跨过一条垂直激光;
沿着一条 常数的线垂直穿过,就会水平跨过一条水平激光。 -
交点计数
如果同时经过一个交点,算两次。那么要最小化穿越次数,我们应该尽量 避免同时经过交点,除非这样可以节省总的穿越数吗?
仔细想:比如从 到 ,经过一个交点意味着你同时跨过了一条水平激光和一条垂直激光,这在路径上是不可避免的吗? -
简化问题
观察一个简单情况:假设没有激光,穿越次数 = 0。
如果有若干激光,我们必须穿过去。
实际上,起点到终点必然会在 方向上跨越所有 的垂线?不一定,因为我们可以走一条弯曲的路径绕过某些激光?
等一下,垂直激光是从 到 ,是贯穿整个 轴的,所以无法绕过——你必须从垂直激光的左边走到右边,而垂直激光挡住了整个 范围,所以你必须穿过它一次(即在 方向跨过 )。
同样,水平激光贯穿整个 轴,所以你必须从水平激光的下方走到上方,因此你必须穿过它一次。
所以:
- 每条垂直激光必须被穿过至少一次。
- 每条水平激光必须被穿过至少一次。
那岂不是答案 = ?
但是示例 1 中 ,答案却是 ,刚好 就是 ,似乎没问题。
但示例 2 中,,答案却是 ,也是 。这让人怀疑是否总是 ?
看另一个情况:如果水平激光和垂直激光有交点,你可以利用交点同时穿过两条激光,从而节省一次穿越吗?
题目明确说了,在交点算两次,所以不会节省。而且你必须分别穿过水平激光的线和垂直激光的线,无法绕过。所以结论:每条激光至少被穿过一次,且无法一次穿过两条(因为交点算两次),所以最少就是 。
但等等——题目给的示例 2,, 匹配,但 ,激光坐标 和 。
为什么答案是 ,就是 ,完全符合。所以所有测试案例答案都是 ?那题目为什么给 范围,以及激光坐标的约束?难道是为了迷惑?
其实这些条件只是说明激光在矩形内部,不接触边界,保证起点和终点不在激光上。
检验是否存在小于 的情况
我们想,是否存在某条路径,少穿过一次激光?
假设你从起点直接沿对角线走到终点,它会穿过一些激光。但要想少穿过一条激光,意味着有一条激光你完全没碰到。但激光是贯穿整个矩形对应方向的,你没法绕过它,因为你要从它的一边到另一边,必然穿过它。所以不可能少过。
因此答案固定为 。
题解结论
对于每个测试用例:
- 读入 。
- 读入 和 (实际不需要用到这些坐标的值,只用到 )。
- 输出 。
标程逻辑
标程中只是生成随机数据,并不是求解代码,但题目原意是统计 。
真正的解题代码非常简单:#include <bits/stdc++.h> using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int t; cin >> t; while (t--) { int n, m; long long x, y; cin >> n >> m >> x >> y; // 读入并丢弃 a[1..n] for (int i = 0; i < n; ++i) { int tmp; cin >> tmp; } // 读入并丢弃 b[1..m] for (int i = 0; i < m; ++i) { int tmp; cin >> tmp; } cout << n + m << '\n'; } return 0; }
复杂度分析
- 每个测试用例 时间。
- 总 和 分别不超过 ,因此总复杂度 。
最终答案
每个测试用例的最小穿越次数就是 。
-
- 1
信息
- ID
- 7275
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 4
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者