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 而且该结构可以很容易的使用数 ...
随机推荐
- dom处理配置文件_待完善
import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java ...
- 当tomcat有两个链接数据库的应用同时运行可能冲突
-Xms512M -Xmx1024M -XX:MaxPermSize=256M
- windows下安装NodeJs
1.官网(//nodejs.org/en/)下载系统匹配的文件 2.双击安装,完成后发现nodejs文件夹下面有npm, 直接用npm安装其他环境既可 3.如果配置了环境变量,直接Win+R后CMD调 ...
- 4位或者5位led数码显示,485通信modbus,支持任意小数点写入,工业标准设置,可和plc,dcs,组态完美对接,支持定制修改
MRD-5030具有4位8段数码管,支持通过工业标注协议Modbus(Modbus-RTU)控制显示,支持任意小数点的显示.数据以半双工方式通信.电源端口和通信端口都具有防浪涌,防雷600W保护,能够 ...
- js返回当前时间的毫秒数
Date.now(); +new Date(); new Date().getTime();
- jquery.lazyload.js图片延迟加载(懒加载)--转载
一.插件介绍 jquery.lazyload.js 是一个用 JavaScript 编写的jQuery 插件. 它可以延迟加载长页面中的图片. 在浏览器可视区域外的图片不会被载入, 直到用户将页面滚动 ...
- InstallShield 工程类型installscript,如何覆盖安装?
原文 http://www.cnblogs.com/daocaorenbx/p/3305162.html 开始使用的msi工程类型.网上找了资料, 在kevin的博客里找到这条方法 可以通过删除Exe ...
- vimTAB宽度等设置
10 set shiftwidth=4 11 set softtabstop=4 12 set textwidth=200 13 set nu 14 set autoindent 15 set noe ...
- 10-3[RF] feature selection
main idea: 计算每一个feature的重要性,选取重要性前k的feature: 衡量一个feature重要的方式:如果一个feature重要,则在这个feature上加上noise,会对最后 ...
- js中调用mangeto的js翻译
第一步: <script type="text/javascript"> Translator.add('英文','<?php echo this->__( ...