题目链接

题目大意:

给n个小车, 每个小车有一个初始位置x和初始速度v, 保证x1 思路:

第一问显然就是一个逆序数, 因为v
第二问, 我们通过观察可以得出一个性质, 超车总是先发生在相邻的两辆车。
比如a, b, c三个车, 如果他们的速度是va > vc > vb, 那么超车肯定是a超过b, 然后才能超过c。 a不可能直接不通过b就超过c。
有了这个性质, 我们可以先将所有相邻的可能发生的超车情况放入一个优先队列。 队列里的元素有4个值, 超车的时间, 超车发生的坐标, 超车的两辆车的编号。
然后初始的时候记录一下每个车前面的车的坐标以及后面的坐标。 初始就是i-1和i+1。
然后如果发生超车, 比如初始是 1, 2, 3, 4。 然后2超过3, 变成1, 3, 2, 4。 每辆车的前后坐标也要改变。 初始pre[2] = 1, nxt[2] = 3,超车之后变成pre[2] = 3, nxt[2] = 4。大概就是这样。 同时1, 3, 4也都会发生改变。
然后每次超车之后, 在将新的可能发生的超车加入队列。 然后这么不断循环。直到队列空或者10000个。
还有一种就是 a, b, c 三个车, va > vb > vc, 然后初始将a超过b, b超过c的情况放入了队列, 这时候b超过了c, 然后将a超过c的情况放入队列。然后a超过c, 再次将a超过b的情况放入队列。如果不判断一下的话就会将a超过b的情况计算两次。 判断的方法, 我是这样的。 比如两辆车a,b。 看nxt[a]是否等于b以及pre[b] 是否等于a, 如果不等于直接continue。

具体的可以看看代码自己想一下... 真是写了好久。

#include <iostream>
#include <vector>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <complex>
#include <cmath>
#include <map>
#include <set>
#include <string>
#include <queue>
#include <stack>
#include <bitset>
using namespace std;
#define pb(x) push_back(x)
#define ll long long
#define mk(x, y) make_pair(x, y)
#define mem(a) memset(a, 0, sizeof(a))
#define fi first
#define se second
typedef pair<int, int> pll;
const double eps = 1e-8;
const int maxn = 250005;
int cnt[100], pre[maxn], nxt[maxn];
double v[maxn], x[maxn];
struct node
{
double t, pos;
int car1, car2;
node(){}
node(double t, double pos, int car1, int car2):t(t), pos(pos), car1(car1), car2(car2){}
bool operator < (node a) const
{
if(fabs(t - a.t)<eps) {
return pos > a.pos;
}
return t > a.t;
}
};
vector <pll> ans;
int main()
{
int n;
while(cin>>n) {
priority_queue <node> q;
ans.clear();
mem(cnt);
mem(pre);
mem(nxt);
int sum = 0;
for(int i = 1; i <= n; i++) {
scanf("%lf%lf", &x[i], &v[i]);
nxt[i] = i+1;
pre[i] = i-1;
cnt[(int)v[i]]++;
for(int j = v[i]+1; j < 100; j++) {
sum += cnt[j];
sum %= 1000000;
}
}
for(int i = 1; i < n; i++) {
if(v[i] > v[i+1]) {
double t = 1.0*(x[i+1]-x[i])/(v[i]-v[i+1]);
q.push(node(t, t*v[i]+x[i], i, i+1));
}
}
int num = 10000;
while(num && !q.empty()) {
node tmp = q.top(); q.pop();
int fi = tmp.car1, se = tmp.car2;
if(nxt[fi] != se || pre[se] != fi)
continue;
ans.pb(mk(fi, se));
nxt[fi] = nxt[se];
pre[se] = pre[fi];
nxt[se] = fi;
pre[fi] = se;
nxt[pre[se]] = se;
pre[nxt[fi]] = fi;
if(pre[se] && v[pre[se]] > v[se]) {
double t = (tmp.pos - v[pre[se]]*tmp.t-x[pre[se]])/(v[pre[se]] - v[se]);
q.push(node(tmp.t + t, tmp.pos + v[se]*t, pre[se], se));
}
if(nxt[fi] != n+1 && v[fi] > v[nxt[fi]]) {
double t = 1.0*(x[nxt[fi]] + v[nxt[fi]]*tmp.t - tmp.pos)/(v[fi] - v[nxt[fi]]);
q.push(node(tmp.t+t, tmp.pos + v[fi]*t, fi, nxt[fi]));
}
num--;
}
cout<<sum<<endl;
for(int i = 0; i < ans.size(); i++) {
printf("%d %d\n", ans[i].fi, ans[i].se);
}
}
return 0;
}

poj 2274 The Race 最小堆的更多相关文章

  1. 最小堆的维护,POJ(2051)

    题目链接:http://poj.org/problem?id=2051 ///维持最小堆(优先队列)POJ2051 #include <iostream> #include <str ...

  2. 《徐徐道来话Java》:PriorityQueue和最小堆

    在讲解PriorityQueue之前,需要先熟悉一个有序数据结构:最小堆. 最小堆是一种经过排序的完全二叉树,其中任一非终端节点数值均不大于其左孩子和右孩子节点的值. 可以得出结论,如果一棵二叉树满足 ...

  3. c++/java/python priority_que实现最大堆和最小堆

    #include<iostream>#include<vector>#include<math.h>#include<string>#include&l ...

  4. 最大堆 最小堆 解决TOPK问题

    堆:实质是一颗完全二叉树,最大堆的特点:父节点值均大于子节点:最小堆的父节点值均小于子节点: 一般使用连续内存存储堆内的值,因而可以根据当前节点的索引值推断子节点的索引值: 节点i的父节点为(i-1) ...

  5. Python3实现最小堆建堆算法

    今天看Python CookBook中关于“求list中最大(最小)的N个元素”的内容,介绍了直接使用python的heapq模块的nlargest和nsmallest函数的解决方式,记得学习数据结构 ...

  6. Google 面试题:Java实现用最大堆和最小堆查找中位数 Find median with min heap and max heap in Java

    Google面试题 股市上一个股票的价格从开市开始是不停的变化的,需要开发一个系统,给定一个股票,它能实时显示从开市到当前时间的这个股票的价格的中位数(中值). SOLUTION 1: 1.维持两个h ...

  7. 【数据结构】通用的最小堆(最大堆)D-ary Heap

    听说有一种最小(大)堆,不限于是完全二叉树,而是完全D叉树,名为D-ary Heap(http://en.wikipedia.org/wiki/D-ary_heap).D可以是1,2,3,4,100, ...

  8. 使用最小堆来完成k路归并 6.5-8

    感谢:http://blog.csdn.net/mishifangxiangdefeng/article/details/7668486 声明:供自己学习之便而收集整理 题目:请给出一个时间为O(nl ...

  9. My集合框架第五弹 最小堆

    二叉堆(以最小堆为例),其具有结构性质和堆序性质结构性质: 堆是一棵完全的二叉树,一颗高为h的完全二叉树有2^h到2^h-1个节点,高度为log N            而且该结构可以很容易的使用数 ...

随机推荐

  1. Android开发环境的搭建之(三)虚拟设备AVD的创建

    选择AVD Manager选项,启动创建AVD向导.根据开发要求创建制定配置的虚拟设备. 设置屏幕大小为17寸,480X800 设置系统映像为API17,X86. 设置AVD Name为MyPhone ...

  2. web.config configSections自定义section

    1.web.config 配置文件设置 <configSections> <!-- For more information on Entity Framework configur ...

  3. css selection改变文字反选的背景颜色

    <style type="text/css"><!--.ai::-moz-selection { background:#cc0000; color:#fff; ...

  4. JavaScript 对象扩展代码

    JavaScript 扩展代码 更具需要写的几个扩展. 扩展核心自执行函数 Object.extend /** * 对象扩展体 参数是 {属性|方法:属性值|方法体} * 只执行实现 * * 实例对基 ...

  5. html5 canvas 画hello ketty

    <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="utf-8& ...

  6. 手机开机提示SD卡受损

    手机开机提示SD卡受损,手机不显示内存卡,有人会选择换新卡或者格式化内存卡,如果刚好木有备份,内存卡上的珍藏丢失了多心痛啊.其实,我们可以通过电脑救活提示受损的内存卡,前后不超过5分钟... 方法:1 ...

  7. C99新特性

    c99标准允许使用变长数组,变的意思是可以根据变量的值来指定数组的维数,如根据用户的输入值指定数组的大小,印象中以前是不可以的.现在在gcc中是可以的(PS:ansi c标准是C90标准): ==== ...

  8. 5款免费Windows远程连接Linux桌面软件(VNC客户端)

        不论我们出于何种的用途目的,很多朋友有需要用到VNC链接Linux桌面环境,之前老左有分享过VNC Viewer绿色软件,昨天有朋友提出来使用之后登录远程桌面的界面.分辨率等有些色差.流畅程度 ...

  9. 元素“Button”不是已知元素。原因可能是网站中存在编译错误,或者缺少web.config文件

    最近开发的时候ASP控件都有波浪下划线,提示不是已知元素,搞得挺郁闷的.虽然不影响变异,不过就是不爽. 折腾N久...... 解决了,把FramWork平台换成3.5,问题解决,不知道为啥,求大神指点 ...

  10. ajax缺点以及解决办法

    1.缺少一个没有标准之争.没有back和history的浏览器    Ajax取消了back按钮,即对浏览器后退机制的破坏.后退按钮是一个标准的web站点的重要功能,但是它没法和js进行很好的合作,这 ...