ACM/ICPC 之 快排+归并排序-记录顺序对(TSH OJ-LightHouse(灯塔))
TsingHua OJ 上不能使用<algorithm>头文件,因此需要手写快排(刚开始写的时候自己就出了很多问题....),另外本题需要在给横坐标排序后,需要记录纵坐标的顺序对的数量,因此,最快的算法貌似只有归并排序或者树状数组的方法进行顺序对的查找和记录了,时间度为O(nlogn),另外此前需要一次对横坐标的排序,这里用快排。
灯塔(LightHouse)
描述
海上有许多灯塔,为过路船只照明。
如图一所示,每个灯塔都配有一盏探照灯,照亮其东北、西南两个对顶的直角区域。探照灯的功率之大,足以覆盖任何距离。灯塔本身是如此之小,可以假定它们不会彼此遮挡。
若灯塔A、B均在对方的照亮范围内,则称它们能够照亮彼此。比如在图二的实例中,蓝、红灯塔可照亮彼此,蓝、绿灯塔则不是,红、绿灯塔也不是。
现在,对于任何一组给定的灯塔,请计算出其中有多少对灯塔能够照亮彼此。
输入
共n+1行。
第1行为1个整数n,表示灯塔的总数。
第2到n+1行每行包含2个整数x, y,分别表示各灯塔的横、纵坐标。
输出
1个整数,表示可照亮彼此的灯塔对的数量。
Example
Input
3
2 2
4 3
5 1
Output
1
限制
对于90%的测例:1 ≤ n ≤ 3×105
对于95%的测例:1 ≤ n ≤ 106
全部测例:1 ≤ n ≤ 4×106
灯塔的坐标x, y是整数,且不同灯塔的x, y坐标均互异
1 ≤ x, y ≤ 10^8
时间:2 sec
内存:256 MB
提示
注意机器中整型变量的范围,C/C++中的int类型通常被编译成32位整数,其范围为[-231, 231 - 1],不一定足够容纳本题的输出。
解题思路:
乱序的坐标对我们解题是没有帮助的,因此我们首先应该想到对横坐标(纵坐标)做一次排序,然后考虑纵坐标(横坐标)。
在这里我先对横坐标进行排序,然后从小到大对纵坐标的要求进行归纳,我们可以发现:如果存在两个灯塔A(x1,y1),B(x2,y2),那么x1<x2时,当且仅当y1<y2时,A B两灯塔才能相互beacon(照亮),因此,这道题可以转化为当横坐标顺序确定时,去记录纵坐标的顺序对数量。
例如A(1,2),B(2,4),C(3,5),那么显然ABC中任两灯塔间可以相互beacon,其对数就是三对。
——我们用顺序对来描述就是:A B C顺序摆放,其中AB,AC,BC的纵坐标(<2,4>,<2,5>,<4,5>)各为一个顺序对,因此有三对灯塔可以相互beacon,这与我们的分析是一致的。
时间度分析:
那么在分析完这道题目后,我们就需要做两件事情,第一件事就是对横坐标进行一次排序,第二件事就是利用某种算法计算出横坐标排序后,纵坐标的顺序对的数量。
在题目中给出 全部测例:1 ≤ n ≤ 4×106 这个数据量是很大的,因此我们必须要用快排对横坐标排序,时间度认为是O(nlogn),第二件事中,联系到逆序对的记录,我们可以用到的最快算法有归并排序和树状数组,这里我们试用归并排序进行顺序对记录,时间度也认为是O(nlogn)。
以下是实现Code:
#include<stdio.h> #define MAX 4000005
long ans; struct Light{
int x, y;
}l[MAX]; int tmp[MAX]; /*快排*/
void quickSort(int low, int high)
{
int i = low;
int j = high;
Light x = l[low]; //设置一个基准点
do{
while (l[i].x < x.x) i++; //Let l[i].x >= x
while (l[j].x > x.x) j--; //Let l[j].x <= x
if(i <= j){ //SWAP
Light t = l[i];
l[i] = l[j];
l[j] = t;
i++; j--;
}
} while (i <= j); //使得p两侧满足 左<=p,右>=p
if(i < high) quickSort(i, high);
if(j > low ) quickSort(low, j);
} void merge(int low, int mid, int high)
{
int s = low, t = mid + , k = low;
while (s <= mid && t <= high){
if (l[s].y < l[t].y){
ans += high - t + ; //顺序对-右侧未放入的date数量
tmp[k++] = l[s++].y;
}
else tmp[k++] = l[t++].y;
}
if (s == mid + ) while (k <= high) tmp[k++] = l[t++].y;
else while (k <= high) tmp[k++] = l[s++].y;
//COPY
for (int i = low; i <= high; i++) l[i].y = tmp[i];
} /*归并排序*/
void mergeSort(int low, int high)
{
if (low < high){
int mid = (low + high) / ;
mergeSort(low, mid);
mergeSort(mid + , high);
merge(low, mid, high);
}
} int main()
{
int n;
scanf("%d", &n);
for (int i = ; i < n; i++)
scanf("%d%d", &l[i].x, &l[i].y);
quickSort(, n - );//横坐标快排
mergeSort(, n - );//纵坐标归并排序并记录顺序对 printf("%ld\n", ans); return ;
}
小墨- -原创
尽管如此,但是我们依然只能A掉95%的样例,说明我们的算法依然不够快,依然要进行优化,那么在这里效果最显著的方法
一个就是改归并排序为树状数组可能相对要更快一些,另一个就是优化手写的快速排序算法,可以采用生成随机数或者采用三数取中等等优化方法使得我们手写的快排更趋近稳定,但是由于时间原因,小编没有尝试下去。
ACM/ICPC 之 快排+归并排序-记录顺序对(TSH OJ-LightHouse(灯塔))的更多相关文章
- 2017 ACM/ICPC Asia Regional Shenyang Online 记录
这场比赛全程心态爆炸…… 开场脑子秀逗签到题WA了一发.之后0贡献. 前期状态全无 H题想复杂了,写了好久样例过不去. 然后这题还是队友过的…… 后期心态炸裂,A题后缀数组理解不深,无法特判k = 1 ...
- 2017 ACM/ICPC Asia Regional Guangxi Online 记录
题目链接 Guangxi 感觉这场比赛完全是读题场啊…… 比赛过程中丢失了一波进度,最后想开题的时候已经来不及了…… Problem A 按题意模拟……按照那个矩阵算就可以了 #include &l ...
- 2017 ACM/ICPC Asia Regional Beijing Online 记录
题目链接 Beijing
- 2017 ACM/ICPC Asia Regional Xian Online 记录
题目链接 Xian
- 2017 ACM/ICPC Asia Regional Qingdao Online 记录
题目链接 Qingdao Problem C AC自动机还不会,暂时暴力水过. #include <bits/stdc++.h> using namespace std; #define ...
- 2017 ACM/ICPC Asia Regional Urumuqi Online 记录
比赛题目链接 Urumuqi
- ACM/ICPC 之 双向链表_构造列表-模拟祖玛 (TSH OJ-Zuma(祖玛))
这一题是TsingHua OJ上的一道题目,学堂在线的一位数据结构老师的题目(原创),所以我直接把题目先贴下来了,这道题对复习双向链表很有帮助,而且也对数据结构中List,也就是对列表的回顾也是很有帮 ...
- ACM/ICPC 之 优先级队列+设置IO缓存区(TSH OJ-Schedule(任务调度))
一个裸的优先级队列(最大堆)题,但也有其他普通队列的做法.这道题我做了两天,结果发现是输入输出太过频繁,一直只能A掉55%的数据,其他都是TLE,如果将输入输出的数据放入缓存区,然后满区输出,可以将I ...
- Java排序算法分析与实现:快排、冒泡排序、选择排序、插入排序、归并排序(二)
一.概述: 上篇博客介绍了常见简单算法:冒泡排序.选择排序和插入排序.本文介绍高级排序算法:快速排序和归并排序.在开始介绍算法之前,首先介绍高级算法所需要的基础知识:划分.递归,并顺带介绍二分查找算法 ...
随机推荐
- Windows10的快捷键和新功能你利用了多少?
win10快捷键大全大家可以来了解一下,今天小编带来了win10常用快捷键,很多朋友喜欢使用快捷键来操作电脑,那么Windows10系统有哪些新的快捷键呢• 贴靠窗口:Win +左/右> Win ...
- jQuery 2.0发布,不再支持IE6/7/8
有时发现jQuery库引用的都对,javascript代码写的也没问题,可是jquery就是出现问题,额--我发现换个jquery库就没问题了,长时间不关注jquery的问题而已: 很多人都没有使用最 ...
- Python网络socket学习
Python 网络编程 Python 提供了两个级别访问的网络服务.: 低级别的网络服务支持基本的 Socket,它提供了标准的 BSD Sockets API,可以访问底层操作系统Socket接口的 ...
- Todd's Matlab讲义第3讲:牛顿法和for循环
方程数值求解 下面几讲,我们将聚集如下方程的解法: \begin{equation} f(x)=0 \tag{3.1}\label{3.1} \end{equation} 在微积分课程中,我们知道,许 ...
- C# 添加excel批注
public bool AddComent(object coment, int row, int column) { try { Excel.Range range = myExcel.get_Ra ...
- 修改dedecms默认文章来源 "未知"改为关键词
在dedecms后台发表文章时文章来源是可选的,有时我们没有选择或没填写,那么前台默认文章来源即“未知”.如何将dedecms默认文章来源改为自己想要的关键词呢?即将“未知”改为“keyword”呢? ...
- Mac Pro 入门、遇到的问题、个性化设置 汇总
入门资料 入门一:Mac 基本用法 入门二:Mac 使用VMware Fusion虚拟机 入门三:Mac 使用brew安装软件 问题汇总 [问题1]如何复制文本? 一只手指头按下,另外一只手指头滑动选 ...
- OS X Framework Library not loaded: 'Image not found'的解决办法
参考:OS X Framework Library not loaded: 'Image not found' 1.首先将相应的framework手动复制到/System/Library/Framew ...
- 修改Mysql默认编码
show variables like 'character%';+--------------------------+----------------------------+| Variable ...
- Java设计模式 之 代理模式
所谓的代理模式就是为其它类或对象提供一个代理以控制对这个对象的访问.那么常见的代理有远程代理,虚拟代理,保护代理,智能代理. 1. 远程代理:为一个不同地址空间的对象提供一个本地代理对象. 2. 虚拟 ...