题目描述

我们有若干架飞机位于地点 AAA ,每架飞机满油可以飞行地球圆周的 a/ba/ba/b 。例如,当 a=1a=1a=1b=2b=2b=2 时,每架飞机可以飞行半个地球(从 AAABBB )。借助高科技,飞机可以瞬间交换燃油(但任何时候飞机携带的燃油不能超过油箱容量)。我们可以使用多架飞机来确保其中一架能够完成环球飞行,并且所有飞机最终都能返回 AAA 。题目要求找出完成这一任务所需的最少飞机数量。

输入格式

第一行包含一个整数 ttt1≤t≤501 \leq t \leq 501t50 ),表示测试用例的数量。每个测试用例包含两个整数 aaabbb0≤a,b≤1500 \leq a, b \leq 1500a,b150b≠0b \neq 0b=0 )。

输出格式

对于每个测试用例,输出格式为 Case X: Y,其中 YYY 是最少所需飞机数。如果 100001000010000 架飞机都不够,则输出 −1-11

题目分析

这是一个经典的燃油接力问题,类似于“沙漠穿越”问题,但增加了环球飞行和对称性的考虑。我们需要让一架飞机(称为环球飞机)飞行整个地球圆周(距离设为 111 ),其他飞机辅助加油并最终全部返回起点。

关键观察

  1. 对称性:由于环球飞行是闭合的,前半程( 0000.50.50.5 )和后半程( 0.50.50.5111 )是对称的。因此,我们可以将辅助飞机分为两组:一组用于前半程,一组用于后半程。

  2. 燃油共享:飞机可以瞬间交换燃油,这意味着当多架飞机一起飞行时,它们的燃油可以视为一个共享的油池。

  3. 折返条件:当一架辅助飞机折返时,它会将剩余燃油均匀分给其他仍在飞行的飞机,确保自己能够返回起点。

数学模型

设:

  • 地球周长 = 111 (单位化)
  • 每架飞机满油可飞行距离 r=a/br = a/br=a/b
  • 前半程使用 iii 架辅助飞机
  • 后半程使用若干架辅助飞机

前半程分析
当有 iii 架辅助飞机时,环球飞机在前半程结束时能飞行的距离为:
s=2ii+1⋅r s = \frac{2i}{i+1} \cdot r s=i+12ir
这个公式的推导基于最优接力策略:当有 kkk 架飞机一起飞行时,它们可以支持环球飞机前进 r/(k+1)r/(k+1)r/(k+1) 的距离,通过累加得到上述结果。

要使环球飞机能够完成飞行,前半程结束时必须满足:
s>1−r s > 1 - r s>1r
否则,即使环球飞机在后半程开始时满油,也无法飞完后半程。

后半程分析
设环球飞机已经飞行了距离 sss ,还需要飞行 1−s1-s1s 的距离。我们逐架添加辅助飞机:

  • 当添加第 jjj 架辅助飞机时,它需要飞行 1−s1-s1s 的距离与环球飞机会合
  • 会合后,它剩余的燃油为 r−(1−s)r - (1-s)r(1s)
  • 这些燃油被平均分给所有 j+1j+1j+1 架飞机(包括环球飞机和已添加的辅助飞机)
  • 因此,环球飞机能飞行的距离增加量为:
    r−(1−s)j+1 \frac{r - (1-s)}{j+1} j+1r(1s)

我们不断添加辅助飞机,直到环球飞机累计飞行距离 s≥1s \geq 1s1

算法步骤

  1. 特判:
    • 如果 a=0a=0a=0 ,输出 −1-11
    • 如果 a≥ba \geq bab ,一架飞机即可环球,输出 111
  2. 枚举前半程辅助飞机数 iii ,从 111 开始:
    • 计算前半程结束距离 s=2ii+1⋅rs = \frac{2i}{i+1} \cdot rs=i+12ir
    • 如果 s≤1−rs \leq 1-rs1r ,说明前半程飞不完,跳过
    • 否则,计算后半程所需辅助飞机数:
      • 初始化 cnt=1cnt = 1cnt=1 (环球飞机)
      • s<1s < 1s<1 时,不断添加辅助飞机,更新 ssscntcntcnt
    • 总飞机数为 i+cnt−1i + cnt - 1i+cnt1
  3. 取所有枚举中的最小值作为答案
  4. 如果答案大于 100001000010000 ,输出 −1-11 ,否则输出答案

时间复杂度

外层循环最多枚举 100001000010000 次,内层循环最多添加 100001000010000 架飞机,但实际运行中会提前剪枝。对于 t≤50t \leq 50t50 的测试数据,可以在时限内通过。

代码实现

// Planes around the World
// UVa ID: 10640
// Verdict: Accepted
// Submission Date: 2026-01-21
// UVa Run Time: 0.000s
//
// 版权所有(C)2026,邱秋。metaphysis # yeah dot net

#include <bits/stdc++.h>
using namespace std;

int main() {
    int t;
    scanf("%d", &t);
    for (int caseNo = 1; caseNo <= t; caseNo++) {
        int a, b;
        scanf("%d %d", &a, &b);
        if (a == 0) {
            printf("Case %d: -1\n", caseNo);
            continue;
        }
        if (a >= b) {
            printf("Case %d: 1\n", caseNo);
            continue;
        }
        double r = (double)a / b;
        int needed = 10001;
        // 枚举前半程辅助飞机数i
        for (int i = 1; i < needed; i++) {
            // 计算前半程结束时环球飞机能飞的距离
            double s = (2.0 * i * a) / ((i + 1.0) * b);
            // 如果前半程飞不完,继续尝试更大的i
            if (s <= 1.0 - r + 1e-9) continue;
            int cnt = 1;  // 已经使用的飞机数(环球飞机)
            while (s < 1.0 - 1e-9) {
                // 如果已经超过当前最优解,提前结束
                if (i + cnt - 1 >= needed) break;
                // 添加一架辅助飞机
                s += (r - (1.0 - s)) / (cnt + 1.0);
                cnt++;
            }
            // 更新答案:前半程i架辅助飞机,后半程(cnt-1)架辅助飞机
            if (s >= 1.0 - 1e-9) needed = min(needed, i + cnt - 1);
        }
        if (needed > 10000) printf("Case %d: -1\n", caseNo);
        else printf("Case %d: %d\n", caseNo, needed);
    }
    return 0;
}

示例验证

样例输入

3
1 2
1 3
2 5

样例输出

Case 1: 5
Case 2: -1
Case 3: 13

对于第一个测试用例( a=1a=1a=1b=2b=2b=2 ):

  • r=0.5r=0.5r=0.5
  • i=3i=3i=3 时, s=0.75>0.5s=0.75 > 0.5s=0.75>0.5
  • 后半程需要添加 222 架辅助飞机( cntcntcnt111 增加到 333
  • 总飞机数 =3+3−1=5= 3 + 3 - 1 = 5=3+31=5

对于第二个测试用例( a=1a=1a=1b=3b=3b=3 ):

  • r≈0.333r \approx 0.333r0.333
  • 需要很大的 iii 才能满足 s>1−r≈0.667s > 1-r \approx 0.667s>1r0.667
  • 计算出的飞机数超过 100001000010000 ,输出 −1-11

对于第三个测试用例( a=2a=2a=2b=5b=5b=5 ):

  • r=0.4r=0.4r=0.4
  • i=6i=6i=6 时, s=0.75>0.6s=0.75 > 0.6s=0.75>0.6
  • 后半程需要添加 666 架辅助飞机
  • 总飞机数 =6+6−1=13= 6 + 6 - 1 = 13=6+61=13

总结

本题的关键在于理解燃油接力的数学模型,特别是对称性带来的简化。通过枚举前半程辅助飞机数,并动态计算后半程所需飞机数,我们可以高效地找到最少飞机数量。算法的时间复杂度在实际数据范围内是可接受的,且能够正确处理边界情况。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐