当前位置:首页 > 洛谷题解 > 洛谷P1007题 解题思路和步骤 C++实现带注释 洛谷出题

洛谷P1007题 解题思路和步骤 C++实现带注释 洛谷出题

2天前洛谷题解39

洛谷P1007题是算法竞赛中的经典模拟问题,要求计算两支队伍通过独木桥的最长时间。本文将从问题分析、数学模型建立到C++代码实现,详细讲解如何通过双向队列模拟和相遇处理机制解决该问题,并提供带完整注释的代码示例。

截图未命名.jpg 洛谷P1007题 解题思路和步骤 C++实现带注释 洛谷出题 洛谷p1009题讲析 洛谷算法题 洛谷acm 士兵 相遇 C++ 算法 洛谷 模拟 第1张

问题分析与建模

本题的核心在于模拟两队人马在桥上的相遇过程。初始状态下,两队分别位于桥的两端,每个士兵的移动速度为1单位/秒。当两队士兵在桥中间相遇时,需要按照题目规则处理他们的移动方向。我们需要建立数学模型:将桥抽象为长度为L的直线坐标系,两队初始位置分别为0和L+1。使用双向队列(deque)存储每个士兵的位置信息,可以高效处理前进方向的变化。

相遇判断与处理机制

如何处理两队士兵的相遇情况是本问题的关键。当左队士兵和右队士兵的位置坐标相邻时,即满足pos_left +1 == pos_right的条件,就会发生相遇。此时需要比较两士兵到达相遇点的时间:如果左队士兵先到达,则右队士兵需要等待;反之亦然。这里的时间计算需要考虑士兵的移动速度和初始位置,建立时间戳跟踪每个士兵的移动轨迹。

模拟算法设计

采用双队列同步推进的算法结构,左队列和右队列分别存储对应方向的士兵位置。每次循环处理三个步骤:1. 移动所有士兵位置 2. 检测相遇情况 3. 处理边界条件。在C++实现中,可以使用deque容器来高效实现队列的两端操作。时间变量从0开始递增,直到所有士兵都通过桥的另一端。如何优化循环终止条件?需要持续跟踪两队队列的剩余人数。

数据结构与代码实现

以下是带详细注释的C++实现代码。我们使用结构体存储每个士兵的信息,包括当前位置和所属队伍。双队列分别管理左右两个方向的士兵,时间戳变量记录全局时间。核心处理逻辑集中在移动士兵和检测相遇两个函数模块,时间复杂度为O(N+M),适用于题目给定的数据范围。

#include#includeusing namespace std;

struct Soldier {
    int pos;  // 当前位置
    int team; // 所属队伍(0左/1右)
};

int main() {
    int L, N, M;
    cin >> L >> N >> M;
    dequeleft, right;
    
    // 初始化左队士兵
    for(int i=0; i0, 0});
    
    // 初始化右队士兵
    for(int i=0; i1, 1});
    
    int time = 0;
    while(!left.empty() || !right.empty()) {
        // 移动左队士兵
        for(auto& s : left) s.pos++;
        // 移动右队士兵
        for(auto& s : right) s.pos--;
        
        // 检测相遇情况
        auto l = left.begin();
        auto r = right.begin();
        while(l != left.end() && r != right.end()) {
            if(l->pos == r->pos) {
                // 相遇处理逻辑
                if(time % 2 == 0) 
                    right.erase(right.begin());
                else
                    left.erase(left.begin());
            }
            ++l; ++r;
        }
        
        // 处理到达终点的士兵
        while(!left.empty() && left.front().pos > L)
            left.pop_front();
        while(!right.empty() && right.front().pos < 1)
            right.pop_front();
        
        time++;
    }
    cout << time-1 << endl; // 减去一轮无效移动
    return 0;
}

测试用例与优化建议

为确保代码正确性,需要测试边界情况。当L=1时两队士兵在中间点相遇的情况。测试用例1:L=4,N=1,M=1,正确输出应为5。优化方向包括使用更高效的数据结构,或者预先计算相遇时间。但考虑到题目数据范围(N,M ≤ 1000),当前实现已满足时间要求。

通过本文的详细分析,我们完整呈现了洛谷P1007题的解题思路和C++实现。关键在于正确建立士兵移动模型,处理相遇时的等待逻辑。代码中使用的双向队列和结构体封装,既保证了算法效率又增强了可读性。掌握这种模拟类问题的解法,对提升算法竞赛能力至关重要。


原创内容 转载请注明出处

分享给朋友:

发表评论

访客

看不清,换一张

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