#USACO652. [USACO 6.5.2]Closed Fences

[USACO 6.5.2]Closed Fences

封闭栅栏

平面上的一个封闭栅栏是由 N 个角点(3 < N < 200)构成的非交叉、相连的线段集合。这些角点互不相同,并按逆时针顺序排列在数组 {xi, yi} 中,i ∈ (1..N)。

每对相邻顶点定义栅栏的一条边。因此对于所有 i ∈ (1..N),{xi yi xi+1 yi+1} 是栅栏的一条边。我们规定 N+1 = 1,因此第一个和最后一个顶点使栅栏闭合。

下面是一个典型的封闭栅栏和一个点 x,y:

                         * x3,y3
                 x5,y5  / \
    x,y *          *   /   \
                  / \ /     \
                 /   *       \
           x6,y6*   x4,y4     \
                |              \
                |               \
           x1,y1*----------------* x2,y2

编写一个程序完成以下任务:

  • 测试一个有序的顶点列表 {xi,yi},i ∈ (1..N),判断该数组是否构成一个有效的栅栏。
  • 找出站在平面上 (x,y) 位置的人(忽略身高)能看到哪些栅栏边。位置 (x,y) 可能位于任何不在栅栏上的地方。

如果存在一条射线连接 (x,y) 与边上的任意一点,且该射线不与任何其他边相交,则这条边是可见的。与视线平行的边视为不可见。上图中,从 (x,y) 可以看到线段 x3,y3-x4,y4、x5,y5-x6,y6 以及 x6,y6-x1,y1 的部分或全部。

程序名称:fence4

输入格式

内容
1 N,栅栏的角点数目
2 两个空格分隔的整数 x 和 y,表示观察者的位置(均在 16 位整数范围内)
3..N+2 每行一对空格分隔的整数,表示一个角点的 X,Y 坐标。这些点按逆时针顺序给出。坐标绝对值不超过 1000

注意:本任务已添加一个新的测试用例 #12。如果认为它有误,请联系 Rob,邮件主题请注明 USACO!

样例输入(文件 fence4.in)

13
5 5
0 0
7 0
5 2
7 5
5 7
3 5
4 9
1 8
2 5
0 9
-2 7
0 3
-3 1 

输出格式

如果序列不是有效的栅栏,输出仅包含单词 "NOFENCE" 的一行。

否则,输出可见的栅栏边,每行一条,用四个空格分隔的整数表示该边的两个端点。在表示线段时,先输出输入中较早出现的点,后输出较晚出现的点。对输出进行排序时,先按线段中第二个点在输入中的顺序升序排列;若相同,再按第一个点的顺序升序排列。

样例输出(文件 fence4.out)

7
0 0 7 0
5 2 7 5
7 5 5 7
5 7 3 5
-2 7 0 3
0 0 -3 1
0 3 -3 1