sgu124

10 篇文章 0 订阅

题目:

124. Broken line

time limit per test: 0.25 sec. 
memory limit per test: 4096 KB

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,yi2all 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

Author: Alex Y. Suslov, Sergey V. Mironov
Resource: 5th Southern Subregional Contest. Saratov 2002
Date: 2002-10-10

题解:

很简单,先看是否有线段覆盖这个点,如果没有,看这个点正上方的线段,如果是平行于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;
}
代码丑陋不要在意

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值