A friend of yours has taken the job of security officer at the Star-Buy Company, a famous department store. One of his tasks is to install a video surveillance system to guarantee the security of the customers (and the security of the merchandise of course) on all of the store’s countless floors. As the company has only a limited budget, there will be only one camera on every floor. But these cameras may turn around to look in every direction.
The first problem is to choose where to install the camera for every floor. The only requirement is that every part of the room must be visible from there. In the following figure the left floor can be completely surveyed from the position indicated by a dot, while for the right floor, there is no such position, the given position failing to see the lower left part of the floor.
Before trying to install the cameras, your friend first wants to know whether there is indeed a suitable position for them. He therefore asks you to write a program that, given a ground plan, determines whether there is a position from which the whole floor is visible. All floor ground plans form rectangular polygons, whose edges do not intersect each other and touch each other only at the corners.
Input
The input file contains several floor descriptions. Every description starts with the number n of vertices that bound th floor(4 <= n <= 100).The next n lines contain two integers each, the x and y coordinates for the n vertices, given in clockwise order. All vertices will be distinct and at corners of the polygon.Thus the edges alternate between horizontal and vertical.
A zero value for n indicates the end of the input.
Output
For every test case first output a line with the number of the floor, as shown in the sample output.
Then print a line stating “Surveillance is possible.” if there exists a position from which the entire floor can be observed, or print “Surveillance is impossible.” if there is no such position.
Print a blank line after each test case.
Sample Input
4
0 0
0 1
1 1
1 0
8
0 0
0 2
1 2
1 1
2 1
2 2
3 2
3 0
0
Sample Output
Floor #1
Surveillance is possible.
Floor #2
Surveillance is impossible.
解体思路:来自于
点击打开链接
限制摄像头位置的,是房间的突出部分,如下图中的ABCD。图一和图二阴影部分表示了突出部分ABCD限制下,摄像头能放置的范围。
所以,如果房间的所有突出部分的限制范围有交集,那交集即可行的区域。
由于墙只有横和竖,只需要记录x和y方向可行的区间。
识别突出部分:沿顺时针方向遍历线段,线段连续右转时,该部分即突出部分。
package OJ;
import java.util.*;
public class P35_temp {
public static void main(String[] args) {
class Point{
int x;
int y;
// public Point(int x, int y){
// this.x = x;
// this.y = y;
// }
}
int tastcase = 0; //表示每个测试集的序号
int xBegin, xEnd;
int yBegin, yEnd;
ArrayList<Point> pointList = new ArrayList<Point>();
ArrayList<Boolean> lineList = new ArrayList<Boolean>();
Scanner in = new Scanner(System.in);
int n = in.nextInt();
while(n != 0){
tastcase++;
int i;
xBegin = xEnd = yBegin = yEnd =0;
pointList.clear();
lineList.clear();
for(i=0; i<n; i++){ //此循环找出所有点中的x,y值的最大值和最小值(即找出一个矩形来将整个图形包括进去),并将每个点加入顶点列表
Point tempP = new Point();
tempP.x = in.nextInt();
tempP.y = in.nextInt();
pointList.add(tempP);
if(tempP.x < xBegin)
xBegin = tempP.x;
if (tempP.x > xEnd)
xEnd = tempP.x;
if (tempP.y < yBegin)
yBegin = tempP.y;
if (tempP.y > yEnd)
yEnd = tempP.y;
}
//??????为什么要把这三个点在加到列表的末尾呢??????
pointList.add(pointList.get(0));
pointList.add(pointList.get(1));
// pointList.add(pointList.get(2));
// pointList.add(pointList.get(3));
//求线段的转向
for(i=0; i<pointList.size()-2; i++){
//求两个向量
Point p01 = new Point();
p01.x = pointList.get(i+1).x - pointList.get(i).x;
p01.y = pointList.get(i+1).y - pointList.get(i).y;
Point p02 = new Point();
p02.x = pointList.get(i+2).x - pointList.get(i).x;
p02.y = pointList.get(i+2).y - pointList.get(i).y;
int cross = p01.x * p02.y - p02.x * p01.y; //向量叉积
if(cross < 0) //第二个向量相对于第一个向量右偏
lineList.add(true);
else //第二个向量相对于第一个向量左偏或者未偏
lineList.add(false);
}
for(i=0; i<lineList.size()-1; i++){
if(lineList.get(i) && lineList.get(i+1)){//连续右转(即i和i+1两个点构成一个凸起边而且方向是朝向凸起方向)
if(pointList.get(i).x == pointList.get(i+1).x){ //与x轴垂直
int begin = pointList.get(i).x;
int end = pointList.get(i+2).x;
if(begin > end){
int t = begin; begin = end; end = t;
}
//这里因为两点连线与x轴垂直,所以接下来可以限制x值的范围
if (begin > xBegin)
{
xBegin = begin;
}
if (end < xEnd)
{
xEnd = end;
}
}
else{
int begin = pointList.get(i).y;
int end = pointList.get(i+2).y;
if (begin > end)
{
int t = begin; begin = end; end = t;
}
//限制y的范围
if (begin > yBegin)
{
yBegin = begin;
}
if (end < yEnd)
{
yEnd = end;
}
}
}
}
System.out.println("Floor #" + tastcase);
//如果四个值能形成正常的矩形,则说明不存在盲区
if (xBegin <= xEnd && yBegin <= yEnd)
{
System.out.println("Surveillance is possible.\n");
}
else
{
System.out.println("Surveillance is impossible.\n" );
}
n = in.nextInt();
}
in.close();
}
}