1 条题解

  • 0
    @ 2025-10-25 20:30:38

    我分析了题目「和 Grundy 玩游戏」和您提供的代码。这道题主要考察几何建模离散化扫描线思想。下面是我的分析。

    算法思路解析

    问题转化

    朋友 ii(xi,0)(x_i, 0),视野是斜率为 ±vihi\pm \frac{v_i}{h_i}向上射线不包括射线本身)构成的三角形区域。小G藏在 (a,Y)(a, Y),其中 a[L,R]a \in [L, R] 且为整数。

    对于朋友 ii,点 (a,Y)(a, Y) 在其视野内部的条件是严格在两条射线之间:

    $$x_i - \frac{h_i \cdot Y}{v_i} < a < x_i + \frac{h_i \cdot Y}{v_i} $$

    注意边界不包含,因为视野不包括射线本身。

    核心算法:差分数组 + 扫描线

    代码使用了离散化差分数组的技巧:

    1. 计算每个朋友的视野区间

      int t = y * h;
      int b = x + ((t % v == 0) ? (t / v) : (t / v + 1)); 
      int a = x - ((t % v == 0) ? (t / v - 1) : (t / v));
      

      这里 a 是左端点(开区间),b 是右端点(开区间)。处理确保了开区间和整数坐标的对应。

    2. 事件点标记

      • 将每个区间拆成两个事件:在 a 处标记开始(覆盖数+1),在 b 处标记结束(覆盖数-1)
      • 使用 pair<int, int> 存储,第二项为 -1 表示开始,+1 表示结束
    3. 扫描线处理

      • 对所有事件点按坐标排序
      • 从左到右扫描,维护当前区域的覆盖数 total
      • 统计每个覆盖数对应的横坐标数量

    代码分析

    关键部分解析

    // 计算每个朋友产生的视野区间
    int t = y * h;
    int b = x + ((t % v == 0) ? (t / v) : (t / v + 1)); 
    int a = x - ((t % v == 0) ? (t / v - 1) : (t / v));
    
    // 存储为事件点
    lines[i*2-1] = make_pair(a, -1);  // 开始
    lines[i*2] = make_pair(b, 1);     // 结束
    
    // 扫描线处理
    int total = 0;
    lines[n*2+1].first = r+1;
    ans[0] += lines[1].first - l;  // 最开始未被覆盖的部分
    
    for(int i = 1; i <= (n<<1); i++){
        total += -lines[i].second;  // 更新覆盖数
        ans[total] += lines[i+1].first - lines[i].first;  // 统计该覆盖数对应的横坐标数
    }
    

    复杂度分析

    • 时间复杂度O(nlogn)O(n \log n),主要来自对 2n2n 个事件点的排序
    • 空间复杂度O(n)O(n),存储事件点和答案数组

    算法标签

    主要分类

    • 离散化 ⭐⭐⭐⭐
    • 扫描线算法 ⭐⭐⭐⭐
    • 几何计算 ⭐⭐⭐

    技术子标签

    • 差分数组 ⭐⭐⭐⭐
    • 事件点处理 ⭐⭐⭐⭐
    • 区间合并 ⭐⭐⭐

    问题类型

    • 计数问题 ⭐⭐⭐
    • 坐标处理 ⭐⭐⭐⭐

    样例验证

    对于样例输入:

    3
    -7 7 3
    0 2 3
    -4 2 1  
    3 3 1
    

    代码计算过程:

    1. 计算每个朋友的视野区间
    2. 生成事件点并排序
    3. 扫描统计每个覆盖数对应的横坐标数量
    4. 输出:5, 12, 15, 15

    算法优势

    1. 高效处理大范围:利用离散化,在 L,RL,R 达到 10910^9 时仍能高效工作
    2. 避免复杂几何判断:将几何问题转化为区间覆盖问题
    3. 输出完整答案:直接得到覆盖数为 00nn 的所有情况

    该解法通过巧妙的事件点建模和扫描线技术,将复杂的几何包含判断转化为简洁的区间统计问题,是大范围几何计数问题的经典解法。

    • 1

    信息

    ID
    4114
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者