象限覆盖 CodeChef Lighthouses

来源:互联网 发布:阿里云高可用 编辑:程序博客网 时间:2024/05/22 10:35

http://www.codechef.com/problems/LIGHTHSE      

PROBLEM:

Given are the coordinates of N islands in cartesian plane. We are supposed to place lighthouses on some or all of these islands such that each one of them gets illuminated. A lighthouse can throw light only in one of the following four directions: North West, North East, South East and South West.

      大洋上共有 N 个岛屿,从 1 到 N 标号。与广袤的大海相比,我们可以认为每个岛都只是平面上的一个点。给定所有岛屿的笛卡尔坐标,坐标系 X 轴指向东,Y 轴指向北。你需要照亮所有的岛屿。为此,你可以在某些岛屿上修建灯塔。每个岛屿至多只能建一座灯塔。每个灯塔可以照亮以它为原点的坐标系的一个象限,即东北、西北、西南、东南的其中之一。注意如果一个岛屿落在光照的边缘,也被认为被照亮了,这意味着修建灯塔的岛屿总是被照亮的。请你找出一个照亮所有岛屿所需灯塔数(记为 L)最小的方案,并输出方案中每个灯塔的位置和方向。

题解:https://discuss.codechef.com/questions/74774/lighthse-editorial

PROBLEM LINK:

Practice
Contest

Author: Evgenij Artemov
Tester: Kevin Atienza
Editorialists: Pushkar Mishra and Suhash Venkatesh

DIFFICULTY:

Easy-Medium

PREREQUISITES:

Ad-hoc

PROBLEM:

Given are the coordinates of N islands in cartesian plane. We are supposed to place lighthouses on some or all of these islands such that each one of them gets illuminated. A lighthouse can throw light only in one of the following four directions: North West, North East, South East and South West.

EXPLANATION:

Subtask 1
In this subtask, there can be a maximum of 8 islands. This clearly hints towards an exponential algorithm. We can try all possible placements of lighthouses and check which one covers all the islands while using the minimum number of lighthouses.

How do we try all possibilities? We can use recursion. Let's say there are N islands, numbered from 0 to N1. We use numbers from i = 0 to 2N1 to denote which islands are lit and which are not. If in the binary representation of a particular i, the jth bit is 1 that means jth island is not lit and if 0 then it is lit.

During the recursion, we place a lighthouse on a particular island and then check how many unlit islands it lights. The placement of lighthouse can be done in 4 ways. To keep a track of the way in which the lighthouse was placed, we use base 5 representation of number. 1 indicates NE, 2 indicates NW, 3 indicates SW and 4 indicates SE.

There are 2N total possible placements. For each placement containing k lighthouses, there are 4k configurations. Upon, placing a lighthouse, we also have to check how many islands it lights. Thus, total complexity comes out to be O(2N4NN) = O(N23N) per test case. Though that looks like it will exceed the time limit, however, the description of subtask 2 will tell us that we don't require more than 2 lighthouses to light all islands. Thus, the depth of this recursion won't be very large.

Subtask 2
Let's consider two particular sets of points:

  • The first set consists of all those islands which have the least x-coordinate value.
  • The second set consists of all those islands which have the highest x-coordinate value.

Now, we can make the following observations:

  • If in the first set, there is an island such that it has the minimum y-coordinate amongst all given N islands, then we can place a lighthouse on it facing in the NE direction. This will illuminate all the islands.
  • If in the first set, there is an island such that it has the maximum y-coordinate amongst all given N islands, then we can place a lighthouse on it facing in the SE direction. This will illuminate all the islands.
  • If in the second set, there is an island such that it has the minimum y-coordinate amongst all given N islands, then we can place a lighthouse on it facing in the NW direction. This will illuminate all the islands.
  • If in the second set, there is an island such that it has the maximum y-coordinate amongst all given N islands, then we can place a lighthouse on it facing in the SW direction. This will illuminate all the islands.

What if none of the aforementioned four conditions are true? Then, we can clearly say that all the islands can't be illuminated by one lighthouse; we need more.

In that case, let's pick up a point from the first set and another from the second set. Let the coordinates of these points be (x1,y1) and (x2,y2) respectively. We know that x1 is the least x-coordinate value amongst all given points and x2 is the highest x-coordinate value amongst all given points. We now consider the following two possibilities:

  • y1y2 In this case, we can place a lighthouse on the island at (x1,y1) facing NE, and another one on the island at (x2,y2) facing SW. This way, we will be able to illuminate all the islands.
  • y1>y2 In this case, we can place a lighthouse on the island at (x1,y1) facing SE, and another one on the island at (x2,y2) facing NW. This way, we will be able to illuminate all the islands.

Thus, we can accomplish the task either by placing 1 or 2 lighthouses, as the case may be. Finding the two sets of points can be done by simple iterations over the set of all the given points. Further steps can also be carried out in O(N).

COMPLEXITY:

O(N) per test case.

SAMPLE SOLUTIONS:

Author
Tester
Editorialist



for cas in xrange(input()):    n = input()    pts = []    for i in xrange(n):        x, y = map(int, raw_input().strip().split())        pts.append((x, y))    minx = min(x for x, y in pts)    maxx = max(x for x, y in pts)    miny = min(y for x, y in pts)    maxy = max(y for x, y in pts)    for i in xrange(n):        if pts[i] == (minx, miny):            print "1\n%d NE" % (i+1)            break        if pts[i] == (minx, maxy):            print "1\n%d SE" % (i+1)            break        if pts[i] == (maxx, miny):            print "1\n%d NW" % (i+1)            break        if pts[i] == (maxx, maxy):            print "1\n%d SW" % (i+1)            break    else:        mini = min(xrange(n), key=lambda i: pts[i])        maxi = max(xrange(n), key=lambda i: pts[i])        if pts[mini][1] < pts[maxi][1]:            print "2\n%d NE\n%d SW" % (mini+1, maxi+1)        else:            print "2\n%d SE\n%d NW" % (mini+1, maxi+1)


0 0
原创粉丝点击