poj 2274 The Race 最小堆
题目链接
题目大意:
给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 最小堆的更多相关文章
- 最小堆的维护,POJ(2051)
题目链接:http://poj.org/problem?id=2051 ///维持最小堆(优先队列)POJ2051 #include <iostream> #include <str ...
- 《徐徐道来话Java》:PriorityQueue和最小堆
在讲解PriorityQueue之前,需要先熟悉一个有序数据结构:最小堆. 最小堆是一种经过排序的完全二叉树,其中任一非终端节点数值均不大于其左孩子和右孩子节点的值. 可以得出结论,如果一棵二叉树满足 ...
- c++/java/python priority_que实现最大堆和最小堆
#include<iostream>#include<vector>#include<math.h>#include<string>#include&l ...
- 最大堆 最小堆 解决TOPK问题
堆:实质是一颗完全二叉树,最大堆的特点:父节点值均大于子节点:最小堆的父节点值均小于子节点: 一般使用连续内存存储堆内的值,因而可以根据当前节点的索引值推断子节点的索引值: 节点i的父节点为(i-1) ...
- Python3实现最小堆建堆算法
今天看Python CookBook中关于“求list中最大(最小)的N个元素”的内容,介绍了直接使用python的heapq模块的nlargest和nsmallest函数的解决方式,记得学习数据结构 ...
- Google 面试题:Java实现用最大堆和最小堆查找中位数 Find median with min heap and max heap in Java
Google面试题 股市上一个股票的价格从开市开始是不停的变化的,需要开发一个系统,给定一个股票,它能实时显示从开市到当前时间的这个股票的价格的中位数(中值). SOLUTION 1: 1.维持两个h ...
- 【数据结构】通用的最小堆(最大堆)D-ary Heap
听说有一种最小(大)堆,不限于是完全二叉树,而是完全D叉树,名为D-ary Heap(http://en.wikipedia.org/wiki/D-ary_heap).D可以是1,2,3,4,100, ...
- 使用最小堆来完成k路归并 6.5-8
感谢:http://blog.csdn.net/mishifangxiangdefeng/article/details/7668486 声明:供自己学习之便而收集整理 题目:请给出一个时间为O(nl ...
- My集合框架第五弹 最小堆
二叉堆(以最小堆为例),其具有结构性质和堆序性质结构性质: 堆是一棵完全的二叉树,一颗高为h的完全二叉树有2^h到2^h-1个节点,高度为log N 而且该结构可以很容易的使用数 ...
随机推荐
- asp.net几种<% %>用法
在asp.net应用程序中,在asp.net页面常用的<%@ %>.<%# %>.<%= %>.在全球化的项目中使用<%$ %>绑定资源项目,在asp. ...
- spark on yarn :state: ACCEPTED一直 出现
今天运行spark on yarn 一直出现 16/09/20 18:40:41 INFO yarn.Client: Application report for application_147417 ...
- ASP.NET版本的Kindeditor插件的使用
1.先从官网中现在最新版本的Kindeditor,官网地址:http://www.kindsoft.net/ 下载之后的目录结构如下:
- ie兼容---haslayout
要想更好的理解 css, 尤其是 IE 下对 css 的渲染,haslayout 是一个非常有必要彻底弄清除的概念.大多IE下的显示错误,就是源于 haslayout. 什么是 haslayout ? ...
- PHP面试题之设计模式
设计模式是技术面试的时候难免会被问到的一个问题,特别会让你举例说明各种设计模式的使用场景. 使用设计模式可以减轻我们的工作量,优化我们的代码. 设计模式非常的多,这里介绍单例模式,工厂模式,组合模式, ...
- 关于Android新建出错:Errors occurred during the build. Errors running builder 'Android Resource M
新建一个eclipse的工作空间就可以了. fuck~
- C++ 常用容器or数据结构
queue 队列 参考 1.入队:如q.push(x):将x元素接到队列的末端: 2.出队:如q.pop() 弹出队列的第一个元素,并不会返回元素的值:T 3,访问队首元素:如q.front() 4, ...
- html5介绍
html5与html4的区别 (h5 and h4) 什么是OPOA 1, 浏览器对h5的支持情况 2, 历史 --- h5 2004年,whatwg 提出 w ...
- Qt5.3.0 for android windows平台下搭建及demo(虫子的博客)
----我的生活,我的点点滴滴!! 部门领导突然心血来潮,想在android平台上做应用,但是我们大多产品属于嵌入式(本吊只负责写写应用,苦比的被强行顶过来搞这,由于这还得领导吵了一架,架虽然吵完了, ...
- docker网络-如何让外部网络访问容器资源
docker网络-如何让外部网络访问容器资源 安装httpd 服务: docker:/root# docker exec -it f63b2633d146 bash bash-4.1# yum ins ...