清华-数据结构-灯塔

来源:互联网 发布:淘宝清仓网址 编辑:程序博客网 时间:2024/05/16 23:46

Description

As shown in the following figure, If another lighthouse is in gray area, they can beacon each other.

For example, in following figure, (B, R) is a pair of lighthouse which can beacon each other, while (B, G), (R, G) are NOT.

Input

1st line: N

2nd ~ (N + 1)th line: each line is X Y, means a lighthouse is on the point (X, Y).

Output

How many pairs of lighthourses can beacon each other

( For every lighthouses, X coordinates won't be the same , Y coordinates won't be the same )

Example

Input

32 24 35 1

Output

1

Restrictions

For 90% test cases: 1 <= n <= 3 * 105

For 95% test cases: 1 <= n <= 106

For all test cases: 1 <= n <= 4 * 106

For every lighthouses, X coordinates won't be the same , Y coordinates won't be the same.

1 <= x, y <= 10^8

Time: 2 sec

Memory: 256 MB

Hints

The range of int is usually [-231, 231 - 1], it may be too small.


解答:

问题的关键在于以下这个数学本质:

-对于每一对儿灯塔的坐标(x_1, y_1)和 (x_2, y_2),他们能彼此照亮当且仅当 (x_1 - x_2) 和 (y_1 - y_2) 同号。

然而如果枚举每一对儿则会造成O(n^2)的时间,不能接受。同时,判断(x_1 - x_2) 和 (y_1 - y_2) 同号与否也要花费大量计算。


所以采取以下等价策略:

对于n对儿灯塔, 先把灯塔们按x坐标排序,然后观察y坐标中有多少逆序对儿(该数量记为count)。然后用nC2 - count即为所求。nC2为n中取2的组合数。


为简单直观起见,给出一个采用bubble sort的基础版本:

main.cpp

#include <iostream>using namespace std;void bubbleSortX(int a[], int b[], int size);long bubbleCount(int a[], int size);int main(){int n;cin >> n;int * a = new int[n];int * b = new int[n];// read in the coordinatesfor (int i = 0; i < n; i++){int x, y;cin >> x >> y;a[i] = x;b[i] = y;}// run bubble sort on x coordinatesbubbleSortX(a, b, n);// calculate the number of reversed pairs on y coordinateslong count = bubbleCount(b, n);// calculate the nC2 number representing all the possible pairs// do division first to avoid integer range exceeding problemlong total = 0;if (n % 2 == 0){total = (n >> 1) * (n - 1);}else{total = n * ((n - 1) >> 1);}cout << (total - count);delete[] a;delete[] b;    return 0;}// The bubble sort algo will record the last place where each iteration conducts a swap,// then use this place as the upper boundary for next iteration. In this way, useless iteration// steps are skiped.void bubbleSortX(int a[], int b[], int size){int last = size;while(last){ int tempLast = 0;for (int i = 0; i < last - 1; i++){if (a[i] > a[i + 1]){int temp = a[i + 1];a[i+1] = a[i];a[i] = temp;int temp2 = b[i + 1];b[i + 1] = b[i];b[i] = temp2;tempLast = i+1;}}last = tempLast;}}long bubbleCount(int a[], int size){int last = size;long count = 0;while (last){int tempLast = 0;for (int i = 0; i < last - 1; i++){if (a[i] > a[i + 1]){int temp = a[i + 1];a[i + 1] = a[i];a[i] = temp;count++;tempLast = i+1;}}last = tempLast;}return count;}


这个版本很简单基础,所以大部分测例都会超时, 但是可以保证是正确的。



0 0
原创粉丝点击