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

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

8小时前

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)是一道经典的算法题目,要求处理在一个二维平面上布置的炸雷与排雷火箭。炸雷具有爆炸半径,当排雷火箭引爆后,会触发周围范围内未被引爆的炸雷,形...

【蓝桥杯2015省赛解析】生命之树:树形DP解题全攻略(洛谷P8625代码详解)

【蓝桥杯2015省赛解析】生命之树:树形DP解题全攻略(洛谷P8625代码详解)

一、题目解读    “生命之树”是一道经典的树形结构问题,要求计算一棵带权树中,以某个节点为根的最大子树权值和。题目输入为n个节点及边信息,每个节点有权值wi,...

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

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

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

【蓝桥杯省赛】2014年A组波动数列题解:动态规划解法与代码解析(C++实现)

【蓝桥杯省赛】2014年A组波动数列题解:动态规划解法与代码解析(C++实现)

一、题目解读“波动数列”是2014年蓝桥杯省赛A组的一道经典题目。题目要求生成一个数列,其前n项的和模n等于给定值s,且每项只能通过加减固定值a、b波动。问题本质是求解满足特定模运算条件的数列组合方案...

洛谷1656题解:基于Tarjan算法求解割边问题(附代码与详细步骤)

洛谷1656题解:基于Tarjan算法求解割边问题(附代码与详细步骤)

一、题目解读洛谷1656题要求在无向图中找出所有割边(即删除后导致图不连通的边)。题目核心在于判断图的连通性,并识别哪些边是“桥”。需理解图论中的连通分量概念,以及如何通过算法高效定位割边。二、解题思...

洛谷2652题解析:同花顺排序问题的动态规划与滑动窗口优化

洛谷2652题解析:同花顺排序问题的动态规划与滑动窗口优化

一、题目解读洛谷2652题要求对一组扑克牌进行排序,目标是找到最少需要调整的次数,使得所有牌形成同花顺。题目中,扑克牌由花色和数字组成,需先按花色排序,再在同花色内按数字排序。核心难点在于如何处理花色...

发表评论

访客

看不清,换一张

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