数据结构与算法实验2020夏第二批(中国石油大学)
PA3题解报告——灯塔(LightHouse)
目录
一、题目描述
1. 描述
海上有许多灯塔,为过路船只照明。
如图一所示,每个灯塔都配有一盏探照灯,照亮其东北、西南两个对顶的直角区域。探照灯的功率之大,足以覆盖任何距离。灯塔本身是如此之小,可以假定它们不会彼此遮挡。
若灯塔A、B均在对方的照亮范围内,则称它们能够照亮彼此。比如在图二的实例中,蓝、红灯塔可照亮彼此,蓝、绿灯塔则不是,红、绿灯塔也不是。
现在,对于任何一组给定的灯塔,请计算出其中有多少对灯塔能够照亮彼此。
2. 输入
共n+1行。
第1行为1个整数n,表示灯塔的总数。
第2到n+1行每行包含2个整数x, y,分别表示各灯塔的横、纵坐标。
3. 输出
1个整数,表示可照亮彼此的灯塔对的数量。
4. 例
//输入
3
2 2
4 3
5 1
//输出
1
5. 限制
对于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
6. 提示
注意机器中整型变量的范围,C/C++中的int类型通常被编译成32位整数,其范围为[-2^31, 2^31 - 1],不一定足够容纳本题的输出。
二、题目分析
1. 方法一【暴力法】
暴力法很简单,首先读入所有灯塔的坐标,从头开始遍历,对于两个灯塔坐标(x1,y1)
和(x2,y2)
,如果满足(x1-x2)(y1-y2)>0
,则两个灯塔均在对方的照亮范围内。
复杂度分析:
- 时间复杂度: O ( n 2 ) O(n^2) O(n2)
- 空间复杂度: O ( n ) O(n) O(n)
2. 方法二【归并排序】
因为不同灯塔的x, y坐标均互异,A和B能够相互照亮的条件就是B在A的右上方或者A在B的右上方。
所以我们就只要我们首先将所有点按照x坐标排序,接下来在y坐标中统计所有“非逆序对”再求和就可以了。
而问题的关键就在于在这样的数据规模下如何快速的统计出“顺序对”的个数。
如果只是单纯的O(n^2)的算法显然是效率不够的(因为我得了50分),而归并排序可以将原问题一分为二的递归下去,最后只将左右两个有序的区间合并起来即可,同时在合并的过程中似乎我们就可以顺便统计“顺序对”的个数。
复杂度分析:
- 时间复杂度: O ( n l o g n ) O(nlogn) O(nlogn)
- 空间复杂度: