杭电 1896 Stones 队列 附题目翻译

Sempr因自行车故障,每日往返行走,途中遇到石头选择投掷或保留。根据输入的石头位置与投掷距离,计算行走后最远石头的距离。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Stones

Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 1357    Accepted Submission(s): 847


Problem Description
Because of the wrong status of the bicycle, Sempr begin to walk east to west every morning and walk back every evening. Walking may cause a little tired, so Sempr always play some games this time.
There are many stones on the road, when he meet a stone, he will throw it ahead as far as possible if it is the odd stone he meet, or leave it where it was if it is the even stone. Now give you some informations about the stones on the road, you are to tell me the distance from the start point to the farthest stone after Sempr walk by. Please pay attention that if two or more stones stay at the same position, you will meet the larger one(the one with the smallest Di, as described in the Input) first.
 

Input
In the first line, there is an Integer T(1<=T<=10), which means the test cases in the input file. Then followed by T test cases.
For each test case, I will give you an Integer N(0<N<=100,000) in the first line, which means the number of stones on the road. Then followed by N lines and there are two integers Pi(0<=Pi<=100,000) and Di(0<=Di<=1,000) in the line, which means the position of the i-th stone and how far Sempr can throw it.
 

Output
Just output one line for one test case, as described in the Description.
 

Sample Input
2 2 1 5 2 4 2 1 5 6 6
 

Sample Output
11 12
Problem Description
Because of the wrong status of the bicycle, Sempr begin to walk east to west every morning and walk back every evening. Walking may cause a little tired, so Sempr always play some games this time.
There are many stones on the road, when he meet a stone, he will throw it ahead as far as possible if it is the odd stone he meet, or leave it where it was if it is the even stone. Now give you some informations about the stones on the road, you are to tell me the distance from the start point to the farthest stone after Sempr walk by. Please pay attention that if two or more stones stay at the same position, you will meet the larger one(the one with the smallest Di, as described in the Input) first.
问题描述
由于自行车的糟糕

### C++ 中优先级队列的使用方法及示例 #### 基本概念 C++ 的 `std::priority_queue` 是一种容器适配器,用于实现优先级队列。它基于堆结构,默认情况下是一个 **大顶堆**(即最大值具有最高优先级),可以通过指定不同的比较方式来改变其行为。 要使用优先级队列,需包含 `<queue>` 头文件[^1]。以下是优先级队列的基本模板定义: ```cpp template<class T, class Container = std::vector<T>, class Compare = std::less<typename Container::value_type>> class priority_queue; ``` 其中: - `T` 表示存储的数据类型; - `Container` 是底层使用的容器类型,默认为 `std::vector`; - `Compare` 定义了元素之间的比较逻辑,默认为 `std::less<T>`, 即构造大顶堆。 --- #### 接口函数 优先级队列提供了以下主要操作接口[^3]: - `push(x)`:向队列中插入一个新元素 `x`。 - `pop()`:移除当前优先级最高的元素(通常是队首元素)。 - `top()`:返回当前优先级最高的元素,但不移除该元素。 - `empty()`:判断队列是否为空。 - `size()`:返回队列中元素的数量。 --- #### 默认用法(大顶堆) 当未提供自定义比较函数时,`std::priority_queue` 将按照默认的大顶堆规则工作。下面是一个简单的例子: ```cpp #include <iostream> #include <queue> int main() { std::priority_queue<int> pq; // 插入一些整数 pq.push(5); pq.push(1); pq.push(8); pq.push(3); // 输出并弹出队列中的元素 while (!pq.empty()) { std::cout << pq.top() << " "; // 打印当前最大的元素 pq.pop(); // 移除当前最大的元素 } return 0; } // 输出结果: 8 5 3 1 ``` 此代码展示了如何创建一个大顶堆,并按从大到小顺序依次取出元素。 --- #### 构造小顶堆 通过更改第三个参数为 `std::greater<T>` 可以构建一个小顶堆。例如: ```cpp #include <iostream> #include <queue> #include <functional> // 提供 greater 函数对象 int main() { std::priority_queue<int, std::vector<int>, std::greater<int>> minHeap; // 插入一些整数 minHeap.push(5); minHeap.push(1); minHeap.push(8); minHeap.push(3); // 输出并弹出队列中的元素 while (!minHeap.empty()) { std::cout << minHeap.top() << " "; // 打印当前最小的元素 minHeap.pop(); // 移除当前最小的元素 } return 0; } // 输出结果: 1 3 5 8 ``` 在此示例中,`std::greater<int>` 被用来反转比较逻辑,从而实现了从小到大的排序[^4]。 --- #### 自定义数据类型的优先级队列 如果需要处理复杂数据类型,则可通过重载运算符或编写自定义比较函数来调整优先级规则。例如,假设有一个表示二维坐标的类 `Point`: ```cpp #include <iostream> #include <queue> #include <cmath> struct Point { double x, y; }; // 计算欧几里得距离平方作为比较依据 bool operator<(const Point& lhs, const Point& rhs) { return (lhs.x * lhs.x + lhs.y * lhs.y) > (rhs.x * rhs.y + rhs.y * rhs.y); // 注意这里是反向比较 } int main() { std::priority_queue<Point> points; // 添加几个点 points.push(Point{3, 4}); points.push(Point{1, 1}); points.push(Point{5, 12}); // 按照离原点的距离由近至远输出 while (!points.empty()) { auto p = points.top(); std::cout << "(" << p.x << ", " << p.y << ") "; points.pop(); } return 0; } // 输出结果可能类似于: (1, 1) (3, 4) (5, 12) ``` 在这个例子中,我们利用了全局范围内的 `<` 运算符重载机制,使得靠近原点的点拥有更高的优先级。 --- #### 实际应用案例 考虑 LeetCode 上的一道题目:“最后一块石头的重量”。给定一堆石头的质量列表,每次取两块最重的石头相撞,直到剩下一块或者没有为止。这正是优先级队列的一个典型应用场景[^2]: ```cpp #include <vector> #include <queue> using namespace std; class Solution { public: int lastStoneWeight(vector<int>& stones) { priority_queue<int> maxHeap(stones.begin(), stones.end()); while (maxHeap.size() > 1) { int first = maxHeap.top(); maxHeap.pop(); int second = maxHeap.top(); maxHeap.pop(); if (first != second) { maxHeap.push(first - second); } } return maxHeap.empty() ? 0 : maxHeap.top(); } }; ``` 上述解决方案借助于优先级队列高效地维护了一个动态的最大值集合。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值