题解:洛谷 P1639 Teleportation

【题目来源】

洛谷:P1639 [USACO18FEB] Teleportation B - 洛谷

【题目描述】

Farmer John 最讨厌的农活是运输牛粪。为了精简这个过程,他制造了一个伟大的发明:便便传送门!与使用拖拉机拖着装满牛粪的大车从一个地点到另一个地点相比,他可以使用便便传送门将牛粪从一个地点瞬间传送到另一个地点。

Farmer John 的农场沿着一条长直道路而建,所以他农场上的每个地点都可以简单地用该地点在道路上的位置来表示(相当于数轴上的一个点)。一个传送门可以用两个数 \(x\)\(y\) 表示,被拖到地点 \(x\) 的牛粪可以瞬间传送到地点 \(y\),反之亦然。

Farmer John 想要将牛粪从地点 \(a\) 运输到地点 \(b\),他建造了一个可能对这一过程有所帮助的传送门(当然,如果没有帮助,他也可以不用)。请帮助他求出他需要使用拖拉机运输牛粪的总距离的最小值。

【输入】

输入仅包含一行,为四个用空格分隔的整数:\(a\)\(b\),表示起始地点和结束地点,后面是 \(x\)\(y\),表示传送门。所有的位置都是范围为 \(0\ldots 100\) 的整数,不一定各不相同。

【输出】

输出一个整数,为 Farmer John 需要用拖拉机运输牛粪的最小距离。

【输入样例】

3 10 8 2

【输出样例】

3

【核心思想】

  1. 问题分析:给定起点 \(a\)、终点 \(b\) 和传送门 \((x, y)\),FJ 可以选择直接步行从 \(a\)\(b\),或步行到传送门一端(\(x\)\(y\)),瞬间传送到另一端,再步行到 \(b\)。求最小总步行距离。这是一个贪心/分类讨论问题,关键在于比较"直接走"与"使用传送门"两种方案的距离。

  2. 算法选择

    • 直接比较:答案 = \(\min(\text{直接距离},\ \text{传送门方案距离})\)
    • 排序规范化:通过交换保证 \(a < b\)\(x < y\),简化后续计算
  3. 关键步骤

    • 读取输入\(a, b, x, y\)
    • 排序规范化
      • \(x > y\):交换 \(x, y\)
      • \(a > b\):交换 \(a, b\)
    • 计算两种方案
      • 直接走:\(|b - a|\)
      • 使用传送门:\(|x - a| + |y - b|\)(从 \(a\) 走到 \(x\),传送到 \(y\),再走到 \(b\)
    • 输出 \(\min(\text{直接走},\ \text{传送门})\)
  4. 时间/空间复杂度

    • 时间复杂度:\(O(1)\),仅若干次绝对值和取最小值
    • 空间复杂度:\(O(1)\),仅需常数个变量
  5. 贪心分类讨论的核心思想

    • 最优子结构:全局最优 = 两种独立方案(直接/传送)的局部最优取较小
    • 对称性消除:通过排序保证 \(a < b\)\(x < y\),消除绝对值带来的分类讨论复杂度
    • 传送门单向最优性:由于传送是双向且瞬时的,从 \(a\) 到较近端 \(x\)、从较远端 \(y\)\(b\) 总是最优(已排序前提下)
    • 适用于"两种策略选优"类基础问题,核心是直接比较所有可行方案

【解题思路】

【算法标签】

入门 #贪心

【代码详解】

#include <bits/stdc++.h>
using namespace std;
int a, b, x, y, ans=0;
// ifstream filein("teleport.in");
// ofstream fileout("teleport.out");
int main()
{
    cin >> a >> b >> x >> y;  // 输入a、b、x和y
    if (x>y) swap(x, y);  // 保证x小于y
    if (a>b) swap(a, b);  // 保证a小于b
    ans = min(abs(b-a), abs(x-a)+abs(y-b));  // 计算b与a的距离,以及通过传送门的距离(即a->x->y->b)的最小值
    cout << ans << endl;  // 打印结果
    return 0;
}

【运行结果】

3 10 8 2
3
posted @ 2026-08-27 11:07  团爸讲算法  阅读(4)  评论(0)    收藏  举报