POJ 2318 TOYS + POJ 2398 Toy Storage (点与直线的位置关系)

本文介绍了解决两个POJ问题的方法,通过使用向量外积和C++ STL中的lower_bound函数来确定纸板上的点数。首先对纸板位置进行排序,然后利用向量外积判断点的位置,并通过lower_bound快速定位。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://poj.org/problem?id=2318


利用向量外积+lower_bound搞定,见代码。

/*172ms,484KB*/

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int mx = 5005;

struct point
{
	int x, y;
	point() {}
	point(int x, int y): x(x), y(y) {}
};

struct vec
{
	point p1, p2;
	vec() {}
	vec(point p1, point p2): p1(p1), p2(p2) {} ///冒号初始化:分配内存空间并赋值
	int cross_product(const vec& v)
	{
		return (p2.x - p1.x) * (v.p2.y - v.p1.y) - (p2.y - p1.y) * (v.p2.x - v.p1.x);
	}
	bool operator < (const point& p) const
	{
		return vec(p1, p2).cross_product(vec(p1, p)) < 0;
	}
} v[mx];

int sum[mx];

int main()
{
	int n, m, x1, y1, x2, y2, i, ux, lx, x, y;
	while (scanf("%d%d%d%d%d%d", &n, &m, &x1, &y1, &x2, &y2), n)
	{
		for (i = 0; i < n; ++i)
		{
			scanf("%d%d", &ux, &lx);
			v[i] = vec(point(lx, y2), point(ux, y1));
		}
		memset(sum, 0, sizeof(sum));
		while (m--)
		{
			scanf("%d%d", &x, &y);
			++sum[lower_bound(v, v + n, point(x, y)) - v];
		}
		for (i = 0; i <= n; ++i) printf("%d: %d\n", i, sum[i]);
		putchar(10);
	}
	return 0;
}

http://poj.org/problem?id=2398


和前面那题一样,不过要先给这些纸板的位置排序。


/*0ms,412KB*/

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int mx = 1005;

struct point
{
	int x, y;
	point() {}
	point(int x, int y): x(x), y(y) {}
};

struct vec
{
	point p1, p2;
	vec() {}
	vec(point p1, point p2): p1(p1), p2(p2) {} ///冒号初始化:分配内存空间并赋值
	int cross_product(const vec& v)
	{
		return (p2.x - p1.x) * (v.p2.y - v.p1.y) - (p2.y - p1.y) * (v.p2.x - v.p1.x);
	}
	bool operator < (const vec& v) const
	{
		return p1.x < v.p1.x;
	}
	bool operator < (const point& p) const
	{
		return vec(p1, p2).cross_product(vec(p1, p)) < 0;
	}
} v[mx];

int sum[mx], cntsum[mx];

int main()
{
	int n, m, x1, y1, x2, y2, i, ux, lx, x, y;
	while (scanf("%d%d%d%d%d%d", &n, &m, &x1, &y1, &x2, &y2), n)
	{
		puts("Box");
		for (i = 0; i < n; ++i)
		{
			scanf("%d%d", &ux, &lx);
			v[i] = vec(point(lx, y2), point(ux, y1));
		}
		sort(v, v + n);
		memset(sum, 0, sizeof(sum));
		for (i = 0; i < m; ++i)
		{
			scanf("%d%d", &x, &y);
			++sum[lower_bound(v, v + n, point(x, y)) - v];
		}
		memset(cntsum, 0, sizeof(cntsum));
		for (i = 0; i <= n; ++i) ++cntsum[sum[i]];
		for (i = 1; i <= m; ++i)
			if (cntsum[i]) printf("%d: %d\n", i, cntsum[i]);
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值