POJ2318 TOYS

嘟嘟嘟


题面:先告诉你一个矩形抽屉的坐标,然后\(n\)个隔板将抽屉分成了\(n + 1\)格(格子从\(0\)\(n - 1\)标号),接下来随机输入\(m\)个玩具的坐标。问最后每一个格子里有多少个玩具。


仔细想想就是一道计算几何入门题。
对于一个玩具\((x_0, y_0)\),我们只要找到在他的左面且离他最近的隔板\(i\),则这个玩具就在第\(i\)格里。
怎么判断隔板\(AB\)(规定\(A\)点是隔板的上端,\(B\)点是隔板下端)是否在玩具的左边?用叉积即可:只要\(\overrightarrow{OA} \times \overrightarrow{OB} > 0\),就说明在左边。
然后因为有人说从左到右枚举会超时,所以我就把枚举改成倍增了。
然鹅枚举\(O(n ^2)\)能过呀,于是我就枚举交了一发,也过了……(???)
代码里注释掉的是枚举的

#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<vector>
#include<stack>
#include<queue>
using namespace std;
#define enter puts("") 
#define space putchar(' ')
#define Mem(a, x) memset(a, x, sizeof(a))
#define rg register
typedef long long ll;
typedef double db;
const int INF = 0x3f3f3f3f;
const db eps = 1e-8;
const int maxn = 5e3 + 5;
inline ll read()
{
	ll ans = 0;
	char ch = getchar(), last = ' ';
	while(!isdigit(ch)) {last = ch; ch = getchar();}
	while(isdigit(ch)) {ans = (ans << 1) + (ans << 3) + ch - '0'; ch = getchar();}
	if(last == '-') ans = -ans;
	return ans;
}
inline void write(ll x)
{
	if(x < 0) x = -x, putchar('-');
	if(x >= 10) write(x / 10);
	putchar(x % 10 + '0');
}

int n, m, xl, yl, xr, yr; 
int ans[maxn];

struct Vec
{
	int x, y;
	int operator * (const Vec& oth)const
	{
		return x * oth.y - oth.x * y;
	}
};
struct Point
{
	int x, y;
	Vec operator - (const Point& oth)const
	{
		return (Vec){x - oth.x, y - oth.y};
	}
}ad[maxn], au[maxn], P;

const int N = 13;
void solve()
{
	int L = 0;
	for(int i = N, t; i >= 0; --i) if((t = L + (1 << i)) <= n)
	{
		if((au[t] - P) * (ad[t] - P) > 0) L = t;
	}
	/*int L = 0;
	while(L < n)
	{
		if((au[L + 1] - P) * (ad[L + 1] - P) < 0) break;
		L++;
	}*/
	ans[L]++;
}

int main()
{
	while(scanf("%d", &n) && n)
	{
		Mem(ans, 0);
		m = read();
		xl = read(); yl = read(); xr = read(); yr = read();
		au[0].y = yl;
		for(int i = 1; i <= n; ++i) 
		{
			au[i].x = read(); au[i].y = yl;
			ad[i].x = read(); ad[i].y = yr;
		}
		for(int i = 1; i <= m; ++i)
		{
			P.x = read(); P.y = read();
			solve();
		}
		for(int i = 0; i <= n; ++i) write(i), putchar(':'), space, write(ans[i]), enter;
		enter;
	}
	return 0;
}
posted @ 2018-11-17 20:40  mrclr  阅读(104)  评论(0编辑  收藏  举报