当前位置:首页 > 蓝桥杯 > 2025蓝桥杯省赛A组地雷阵题解:几何转化与区间合并算法详解

2025蓝桥杯省赛A组地雷阵题解:几何转化与区间合并算法详解

2个月前 (07-17)

2025蓝桥杯省赛A组地雷阵题解:几何转化与区间合并算法详解 蓝桥杯省赛 地雷阵题解 概率计算 蓝桥杯 蓝桥杯比赛 洛谷题解 第1张

一、题目解读

2025年蓝桥杯省赛A组地雷阵题目(洛谷12144)要求计算在平面直角坐标系第一象限中,给定n个地雷的位置坐标和触发半径,从原点出发随机选择一个方向行走,不触发地雷的通关概率。题目将游戏问题转化为几何计算:需统计危险角度区间,并通过概率公式求解。

二、解题思路

核心思想是几何转化+区间合并:

1. 危险角度计算:每个地雷对应一个危险角度区间,通过计算地雷圆心到原点连线与x轴的夹角α及切线夹角θ,得到区间[α-θ, α+θ]。

2. 区间合并:合并重叠区间,减少危险角度总量,避免重复计算。

3. 概率计算:用总危险角度占[0, π/2]的比例,反推安全概率。

特殊处理:若原点在地雷范围内,直接输出0,避免后续计算。

三、解题步骤

1. 输入与预处理:读取n个地雷的(x,y,r),判断原点是否在地雷内。

2. 计算单个危险区间:

    计算地雷到原点距离d与夹角α。

    若d≤r,原点触发,结束;否则计算切线夹角θ,形成区间[L, R]。

3. 合并区间:

    按左端点排序,遍历合并重叠区间(如新区间与当前区间右端重叠,扩展右端)。

4. 计算总危险角度:累加合并后区间的长度。

5. 输出概率:1 - (危险角度 / π/2),保留三位小数。

四、代码及注释

#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <iomanip>

using namespace std;

const double PI = acos(-1.0);

// 表示一个角度区间
struct Interval {
    double l, r;
    Interval(double _l = 0, double _r = 0) : l(_l), r(_r) {}
    bool operator<(const Interval& other) const {
        return l < other.l;
    }
};

int main() {
    int n;
    cin >> n;
    vector<Interval> intervals;
    
    for (int i = 0; i < n; ++i) {
        double x, y, r;
        cin >> x >> y >> r;
        
        // 计算地雷中心到原点的距离
        double d = sqrt(x * x + y * y);
        if (d <= r) {
            // 如果原点在地雷范围内,所有方向都会触发地雷
            cout << "0.000" << endl;
            return 0;
        }
        
        // 计算切线与x轴的夹角
        double theta = asin(r / d);
        // 计算地雷中心与x轴的夹角
        double alpha = atan2(y, x);
        
        // 计算危险角度区间
        double L = alpha - theta;
        double R = alpha + theta;
        
        // 确保角度在[0, PI/2]范围内
        if (R < 0) continue; // 完全在左边,不影响
        if (L > PI/2) continue; // 完全在右边,不影响
        
        L = max(L, 0.0);
        R = min(R, PI/2);
        
        if (L < R) {
            intervals.emplace_back(L, R);
        }
    }
    
    // 合并重叠的区间
    if (!intervals.empty()) {
        sort(intervals.begin(), intervals.end());
        vector<Interval> merged;
        merged.push_back(intervals[0]);
        
        for (int i = 1; i < intervals.size(); ++i) {
            if (intervals[i].l <= merged.back().r) {
                merged.back().r = max(merged.back().r, intervals[i].r);
            } else {
                merged.push_back(intervals[i]);
            }
        }
        
        intervals = merged;
    }
    
    // 计算总危险角度范围
    double danger = 0;
    for (const auto& interval : intervals) {
        danger += interval.r - interval.l;
    }
    
    // 输出安全概率
    cout << fixed << setprecision(3) << 1 - (danger / (PI / 2));
}

注释说明:

● Interval结构定义角度区间,用于存储危险范围。

● atan2(y, x)计算带象限的反正切,确保角度正确。

● 区间合并逻辑通过贪心策略,维护左端点递增的区间列表。

五、总结

该解法巧妙将地雷触发问题转化为角度区间计算,通过几何转化降低复杂度。区间合并算法是核心,需注意边界处理(原点触发、角度范围限制)。代码简洁高效,适用于大规模数据。未来可优化合并过程的时间复杂度,或采用更精确的几何算法提升性能。



原创内容 转载请注明出处

分享给朋友:

相关文章

2022年蓝桥杯省赛B组扫雷(洛谷P8785)解题全解析:代码+思路+步骤详解

2022年蓝桥杯省赛B组扫雷(洛谷P8785)解题全解析:代码+思路+步骤详解

一、题目解读2022年蓝桥杯省赛B组机器人塔(洛谷P8785)是一道经典的算法题目,要求处理在一个二维平面上布置的炸雷与排雷火箭。炸雷具有爆炸半径,当排雷火箭引爆后,会触发周围范围内未被引爆的炸雷,形...

牛客4580题解:动态规划求解网格路径概率问题(C++代码实现)

牛客4580题解:动态规划求解网格路径概率问题(C++代码实现)

一、题目解读牛客4580题要求在一个n×m的网格中计算从起点(1,1)到终点(n,m)的概率。网格中存在障碍物(标记为坏点),路径只能向右或向下移动。到达终点时,若处于边界位置,概率转移规则不同:下边...

洛谷P2190题解:铁路售票系统车厢计算(差分数组+前缀和优化)

洛谷P2190题解:铁路售票系统车厢计算(差分数组+前缀和优化)

一、题目解读洛谷P2190题要求解决铁路售票系统中的车厢数量计算问题。题目给定n个车站和m条订票申请,每条申请包含区间[x,y)及乘客数z。需要计算在不超载的情况下(每节车厢最多36人),满足所有乘客...

洛谷P2789题解:递归算法与避免重复计算的技巧

洛谷P2789题解:递归算法与避免重复计算的技巧

一、题目解读洛谷P2789题要求计算n条直线在平面上两两相交产生的交点总数。题目强调交点不重复,需考虑平行线情况。关键点在于如何高效枚举所有可能的交点组合,并排除重复结果。二、解题思路采用递归算法,核...

洛谷P1438题解:基于线段树的等差数列

洛谷P1438题解:基于线段树的等差数列

一、题目解读洛谷P1438题要求处理数列的区间更新与单点查询操作,其中更新方式为给定区间内元素按等差数列递增。传统暴力修改会因多次区间遍历导致超时,需设计高效数据结构——线段树,结合等差数列性质实现O...

NOIP2002普及组过河卒题解:动态规划解法与代码详解

NOIP2002普及组过河卒题解:动态规划解法与代码详解

一、题目解读“过河卒”是2002年NOIP普及组的经典题目(洛谷P1002),要求计算棋盘上卒从A点(0,0)到达B点(n,m)的路径条数。卒仅能向右或向下移动,但需避开马的控制点(马的位置及跳跃一步...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。