题目:
124. Broken line time limit per test: 0.25 sec. There is a closed broken line on a plane with sides parallel to coordinate axes, without self-crossings and self-contacts. The broken line consists of K segments. You have to determine, whether a given point with coordinates (X0,Y0) is inside this closed broken line, outside or belongs to the broken line. Input The first line contains integer K (4 Ј K Ј 10000) - the number of broken line segments. Each of the following N lines contains coordinates of the beginning and end points of the segments (4 integerxi1,yi1,xi2,yi2; all numbers in a range from -10000 up to 10000 inclusive). Number separate by a space. The segments are given in random order. Last line contains 2 integers X0 and Y0 - the coordinates of the given point delimited by a space. (Numbers X0, Y0 in a range from -10000 up to 10000 inclusive). Output The first line should contain: INSIDE - if the point is inside closed broken line, OUTSIDE - if the point is outside, BORDER - if the point belongs to broken line. Sample Input 4 0 0 0 3 3 3 3 0 0 3 3 3 3 0 0 0 2 2 Sample Output INSIDE | ||||||
|
题解:
很简单,先看是否有线段覆盖这个点,如果没有,看这个点正上方的线段,如果是平行于x轴,则ans+1,如果平行于y轴且上下两端点所连接的线段不在同一边则ans+1否则不变。如果ans % 2 等于0则点在多边形之外,否则在多边形之内。
从一本数学书上看到的方法,证明的话。。。就不知道了。。。
代码:
#include <cstdio>
using namespace std;
struct node
{
int startx, endx, starty, endy;
}line[10005];
int n, pointx, pointy, ans = 0;)
bool check[10005] = {false};//check[i]表示第i条线段是否可用(false为可用),即是否有另一条线段与之在同一条直线上且相邻(仅考虑平行于y轴的线段)
void init()
{int changex, changey;
scanf("%d", &n);
for (int i = 1; i <= n; i++)
{
scanf("%d%d%d%d", &line[i].startx, &line[i].starty, &line[i].endx, &line[i].endy);
if (line[i].startx > line[i].endx || line[i].starty > line[i].endy)
{
changex = line[i].startx;
changey = line[i].starty;
line[i].startx = line[i].endx;
line[i].starty = line[i].endy;
line[i].endx = changex;
line[i].endy = changey;
}
}
for (int i = 1; i <= n; i++)
if (!check[i] && line[i].startx == line[i].endx)
for (int j = i + 1; j <= n; j++)
if (!check[j] && line[j].startx == line[j].endx)
{
if (line[i].endx == line[j].startx && line[i].endy == line[j].starty)
{
check[j] = true;
line[i].endy = line[j].endy;
}
if (line[i].startx == line[j].endx && line[i].starty == line[j].endy)
{
check[j] = true;
line[i].starty = line[j].starty;
}
}
scanf("%d%d", &pointx, &pointy);
}
bool on(struct node xd)
{
if (xd.startx > pointx) return false;
if (xd.starty > pointy) return false;
if (xd.endx < pointx) return false;
if (xd.endy < pointy) return false;
return true;
}
bool upward(struct node xd)
{int onright = 0, onleft = 0;
if (xd.startx == xd.endx)
if (xd.startx == pointx && xd.endy > pointy)
{
for (int i = 1; i <= n; i++)
{
if (line[i].startx == xd.endx && line[i].starty == xd.endy) onright++;
if (line[i].startx == xd.startx && line[i].starty == xd.starty) onright++;
if (line[i].endx == xd.endx && line[i].endy == xd.endy) onleft++;
if (line[i].endx == xd.startx && line[i].endy == xd.starty) onleft++;
}
if (onright == onleft) return true;
else return false;
}
if (xd.starty == xd.endy)
if (xd.starty > pointy && xd.startx <= pointx && xd.endx >= pointx)
return true;
return false;
}
int main()
{
init();
for (int i = 1; i <= n; i++)
if (!check[i])
if (on(line[i]))
{
printf("BORDER\n");
return 0;
}
for (int i = 1; i <= n; i++)
if (!check[i])
if (upward(line[i]))
ans++;
if (ans % 2 == 1) printf("INSIDE\n");
else printf("OUTSIDE\n");
return 0;
}
代码丑陋不要在意