0

Problem Description:

There are many light house in the sea. The range of the sea is [1, 10^7] × [1, 10^7].

Each light house can light up the south-west and north-east area. The power of the light is enought to cover any distance.

enter image description here

If the light house A and B are in there lighting up area, says they can illuminate each other.

input has n+1 lines: the first line is the number of light house. the second line to the nth line are the horizontal and vertical coordinate of the light house.

output has one line: the pair of light house which can illuminate each other.

for example:

intput:

3
2 2
4 3
5 1

output:

1

note:

The coordinate of the light house is int. The horizontal and vertical coordinate of all the light houses are different.

1 ≤ x, y ≤ 10^7

the efficiency of my code is very low. Please help me revise my code. Thank you very much!

Here is my code.

    #include<stdlib.h>
    int main()
    {
        int n,i,j,s;
        int *x,*y;
        scanf("%d",&n);
        x=(int *)malloc(n*sizeof(int));
        y=(int *)malloc(n*sizeof(int));
        for(i=0;i<n;i++)
        {
           scanf("%d %d",&x[i],&y[i]);
        }
        s=0;
        for(i=0;i<n-1;i++)
        for(j=i+1;j<n;j++)
        {
        if((x[i]>x[j]&&y[i]>y[j])||(x[i]<x[j]&&y[i]<y[j]))
            s++;
        }
        printf("%d\n",s);
        free(x);
        free(y);
        return 0;
        }
Ray
  • 2,472
  • 18
  • 22
muddytu
  • 17
  • 1
  • Are you following Data Structures on xuetangX? Or you come across this lighthouse problem somewhere else? – Ray Dec 17 '13 at 05:46
  • If so, there is a special hint video on tag 第零章 – Ray Dec 17 '13 at 06:05
  • Yes,its the problem on the xuetangX. I cannot solve it. – muddytu Dec 17 '13 at 12:46
  • Just check the video out, something similar to mergesort taking `O(nlogn)` better than your `O(n^2)` – Ray Dec 17 '13 at 12:52
  • Two lighthouse (x1, y1) and (x2, y2) can illuminate each other if, and only if, one light house, say (x2, y2), satisfies x1 <= x2 and y1 <= y2. The problem becomes for each point (x, y), how many points (x', y') satisfies x' <= x and y' <= y. In order to solve this problem, you can use divide-and-conquer technique. Split the set by x-coordinate into two equal size sets and solve the problem recursively. For a lighthouse (x', y') in the left half and (x, y) in the right half, since x' <= x by construction, they can illuminate each other if y' <= y. Based on this, you can solve the problem. – Yu-Han Lyu Dec 17 '13 at 13:02
  • (x,y) is in pair, when I sort the x, how can I do with y? – muddytu Dec 18 '13 at 07:42

1 Answers1

1

I don't have enough reputation to leave a comment directly, so I'll be detailed and leave an answer here.

Your algorithm does pair wise computation with a nested loop and has O(n2) temporal complexity, that's why your algorithm is slow for large inputs (large here doesn't mean the coordinate values, but the number of light houses). First let's see what we could do to optimize, with a sample input:

3
1 1 (Pa)
2 2 (Pb)
3 3 (Pc)

With your algorithm, the execution logic would be:

  1. count=0
  2. Pa and Pb is a pair? True, count++
  3. Pa and Pc is a pair? True, count++
  4. Pb and Pc is a pair? True, count++
  5. output count

There are actually redundant computations which could be eliminated:

Determine whether a newly added light house could be illuminated by existing light houses.

Note that Pa's NE region actually contains Pb's NE region, so if a new light house falls into Pb's NE region, that implicitly means it's illuminated by Pa, as well as Pb. So if we have Pa and Pb in the sea and add Pc, we actually don't need to compute twice with Pa and Pb separately.

Say if we have the following record which records the the illumination intersection areas of light houses:
a. count=0; R={}
b. add Pa, R={[(-∞,-∞),(1,1)]->[Pa],[(1,1),(∞,∞)]->[Pa]} ([(-∞,-∞),(1,1)] and [(1,1),(∞,∞)] define two rectangular areas with their diagonal points)
c. add Pb, Pb is in [(1,1),(∞,∞)] (that means [Pa] can illuminate Pb), find all light houses in [Pa] that could be illuminated by Pb, that's Pa, count+=1, R={[(-∞,-∞),(1,1)]->[Pa,Pb],[(-∞,1),(1,2)]->[Pb],[(1,-∞),(2,1)]->[Pb],[(1,1),(2,2)]->[Pa,Pb],[(1,2),(2,∞)]->[Pb],[(2,1),(∞,2)]->[Pb],[(2,2),(∞,∞)]->[Pa,Pb]}
d. add Pc, Pc is in [(2,2),(∞,∞)], find all light houses in [Pa,Pb] that could be illuminated by [Pa,Pb], that's Pa,Pb, count+=2, update R (will be too long so I'll just omit it here)

enter image description here

One data structure you may want to represent R is a segment tree1. The segment tree applicable here would be two-dimensional. I suggest you have a look at existing post like How to code 2D segment tree? and try to implement your own.

1 http://en.wikipedia.org/wiki/Segment_tree

Community
  • 1
  • 1