OJ 灯塔(LightHouse)有关问题求解
OJ 灯塔(LightHouse)问题求解
题目如下
描述
海上有许多灯塔,为过路船只照明。

如图一所示,每个灯塔都配有一盏探照灯,照亮其东北、西南两个对顶的直角区域。探照灯的功率之大,足以覆盖任何距离。灯塔本身是如此之小,可以假定它们不会彼此遮挡。

若灯塔A、B均在对方的照亮范围内,则称它们能够照亮彼此。比如在图二的实例中,蓝、红灯塔可照亮彼此,蓝、绿灯塔则不是,红、绿灯塔也不是。
现在,对于任何一组给定的灯塔,请计算出其中有多少对灯塔能够照亮彼此。
输入
共n+1行。
第1行为1个整数n,表示灯塔的总数。
第2到n+1行每行包含2个整数x, y,分别表示各灯塔的横、纵坐标。
输出
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],不一定足够容纳本题的输出。
下面是我的实现代码
看了很长时间不知道为什么后面那么多过不了,求大神解答。感激不尽。
------解决思路----------------------
long sum =
你确定long是64位么
题目如下
描述
海上有许多灯塔,为过路船只照明。
如图一所示,每个灯塔都配有一盏探照灯,照亮其东北、西南两个对顶的直角区域。探照灯的功率之大,足以覆盖任何距离。灯塔本身是如此之小,可以假定它们不会彼此遮挡。
若灯塔A、B均在对方的照亮范围内,则称它们能够照亮彼此。比如在图二的实例中,蓝、红灯塔可照亮彼此,蓝、绿灯塔则不是,红、绿灯塔也不是。
现在,对于任何一组给定的灯塔,请计算出其中有多少对灯塔能够照亮彼此。
输入
共n+1行。
第1行为1个整数n,表示灯塔的总数。
第2到n+1行每行包含2个整数x, y,分别表示各灯塔的横、纵坐标。
输出
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],不一定足够容纳本题的输出。
下面是我的实现代码
//这是这段代码的运行结果
//http://dsa.cs.tsinghua.edu.cn/oj/result/1f3c4dc4503b191ce41db4306effc6cf8c19c252.html
#include <stdio.h>
#include <stdlib.h>
#define NMAX 4000005
class Node
{
public:
int xLoca;
int yLoca;
Node(){}
Node(int const& x, int const& y){ xLoca = x; yLoca = y; }
~Node(){}
};//为点创建类
Node lightLoca[NMAX];
long yLocaOfLight[NMAX];
long result = 0;
void quicksort(Node v[], int left, int right){
if (left < right){
Node temp = v[left];
int key = v[left].xLoca;
int low = left;
int high = right;
while (low < high){
while (low < high && v[high].xLoca >= key){
high--;
}
v[low] = v[high];
while (low < high && v[low].xLoca <= key){
low++;
}
v[high] = v[low];
}
v[low] = temp;
quicksort(v, left, low - 1);
quicksort(v, low + 1, right);
}
}//针对点的x坐标快速排序
void merge(int low, int middle, int high){
long leNum = middle - low;
long riNum = high - middle;
long *le = new long[leNum];
long *ri = new long[riNum];
for (int lowInd = 0; lowInd < leNum; lowInd++){
le[lowInd] = yLocaOfLight[low+lowInd];
}
for (int highInd = 0; highInd < riNum; highInd++){
ri[highInd] = yLocaOfLight[middle+highInd];
}
for (long i = 0, j = 0, k = 0; j < leNum;){
if ((k < riNum) && (ri[k] < le[j])){
yLocaOfLight[low + i] = ri[k];
i++; k++;
result = result + leNum - j;
}
if ((riNum <= k) || (le[j] <= ri[k])){
yLocaOfLight[low + i] = le[j]; i++; j++;
}
}
delete le;
delete ri;
}//合并两个有序序列,在右边序列某项的值小于左边序列时,将左边序列大于该项的值的元素个数累加入result
void mergeSort(int low, int high){
if (high - low < 2){ return; }
int middle = (high + low) / 2;
mergeSort(low, middle);
mergeSort(middle, high);
merge(low, middle, high);
}//归并排序
int main(){
int spotNum;
scanf("%d", &spotNum);//输入所有点的个数
for (int inputInd = 0; inputInd < spotNum; inputInd++){
int xloca;
int yloca;
scanf("%d %d", &xloca, &yloca);
lightLoca[inputInd] = Node(xloca, yloca);
}//将所有点依次存入lightLoca[]
quicksort(lightLoca, 0, spotNum - 1);//按照x坐标从小到大对lightLoca进行排序
for (int storeInd = 0; storeInd < spotNum; storeInd++){
yLocaOfLight[storeInd] = lightLoca[storeInd].yLoca;
}//将排序后的y坐标顺序存入yLocaOfLight[]
//for (int show = 0; show < spotNum; show++){
// printf("%d ", yLocaOfLight[show]);
//}
//printf("\n");
mergeSort(0, spotNum);//对yLocaOfLight归并排序
//for (int show = 0; show < spotNum; show++){
// printf("%d ", yLocaOfLight[show]);
//}
//printf("\n");
long sum = (spotNum * (spotNum - 1)) / 2;//所有组合数减去逆序对个数
printf("%ld", sum-result);
system("pause");
return 0;
}
看了很长时间不知道为什么后面那么多过不了,求大神解答。感激不尽。
------解决思路----------------------
long sum =
你确定long是64位么