【POJ】2318 TOYS(计算几何+暴力)

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

第一次完全是$O(n^2)$的暴力为什么被卡了~QAQ(一定是常数太大了...)

后来排序了下点然后单调搞了搞。。(然而还是可以随便造出让我的code变成$O(n^2)$的23333)

#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <iostream>
#include <algorithm>
#include <queue>
#include <set>
#include <map>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
#define mkpii make_pair<int, int>
#define pdi pair<double, int>
#define mkpdi make_pair<double, int>
#define pli pair<ll, int>
#define mkpli make_pair<ll, int>
#define rep(i, n) for(int i=0; i<(n); ++i)
#define for1(i,a,n) for(int i=(a);i<=(n);++i)
#define for2(i,a,n) for(int i=(a);i<(n);++i)
#define for3(i,a,n) for(int i=(a);i>=(n);--i)
#define for4(i,a,n) for(int i=(a);i>(n);--i)
#define CC(i,a) memset(i,a,sizeof(i))
#define read(a) a=getint()
#define print(a) printf("%d", a)
#define dbg(x) cout << (#x) << " = " << (x) << endl
#define error(x) (!(x)?puts("error"):0)
#define printarr2(a, b, c) for1(_, 1, b) { for1(__, 1, c) cout << a[_][__]; cout << endl; }
#define printarr1(a, b) for1(_, 1, b) cout << a[_] << ‘\t‘; cout << endl
inline const ll getint() { ll r=0, k=1; char c=getchar(); for(; c<‘0‘||c>‘9‘; c=getchar()) if(c==‘-‘) k=-1; for(; c>=‘0‘&&c<=‘9‘; c=getchar()) r=r*10+c-‘0‘; return k*r; }
inline const int max(const int &a, const int &b) { return a>b?a:b; }
inline const int min(const int &a, const int &b) { return a<b?a:b; }

const int N=5015;
struct dat { ll x, y; }E[2], a[N][2], b[N];
ll Cross(dat &a, dat &b, dat &c) {
	static ll x1, x2, y1, y2;
	x1=a.x-c.x; y1=a.y-c.y;
	x2=b.x-c.x; y2=b.y-c.y;
	return x1*y2-x2*y1;
}
int ans[N];

bool check(dat &l1, dat &l2, dat &r1, dat &r2, dat &p) {
	if(Cross(p, l1, l2)*Cross(p, r1, r2)<0) return 1;
	return 0;
}

int n, m;
void work(int last, dat p) {
	int xxx=n+1;
	for1(now, last, xxx) {
		if(check(a[now-1][0], a[now-1][1], a[now][0], a[now][1], p)) { ++ans[now-1]; return; }
	}
}

bool cmp(const dat &a, const dat &b) { return a.x<b.x; }

int main() {
	while(read(n), n) {
		read(m);
		rep(i, 2) read(E[i].x), read(E[i].y);
		a[0][0].x=E[0].x; a[0][0].y=E[0].y;
		a[0][1].x=E[0].x; a[0][1].y=E[1].y;
		a[n+1][0].x=E[1].x; a[n+1][0].y=E[0].y;
		a[n+1][1].x=E[1].x; a[n+1][1].y=E[1].y;
		for1(i, 1, n) rep(k, 2) read(a[i][k].x), a[i][k].y=E[k].y;
		for1(i, 1, m) read(b[i].x), read(b[i].y);
		sort(b+1, b+1+m, cmp);
		int last=1;
		for1(i, 1, m) {
			while(last<=n && max(a[last][0].x, a[last][1].x)<b[i].x) ++last;
			work(last, b[i]);
		}
		rep(i, n+1) printf("%d: %d\n", i, ans[i]), ans[i]=0;
		puts("");
	}
	return 0;
}

  



Description

Calculate the number of toys that land in each bin of a partitioned toy box. 
Mom and dad have a problem - their child John never puts his toys away when he is finished playing with them. They gave John a rectangular box to put his toys in, but John is rebellious and obeys his parents by simply throwing his toys into the box. All the toys get mixed up, and it is impossible for John to find his favorite toys.

John‘s parents came up with the following idea. They put cardboard partitions into the box. Even if John keeps throwing his toys into the box, at least toys that get thrown into different bins stay separated. The following diagram shows a top view of an example toy box. 
 
For this problem, you are asked to determine how many toys fall into each partition as John throws them into the toy box.

Input

The input file contains one or more problems. The first line of a problem consists of six integers, n m x1 y1 x2 y2. The number of cardboard partitions is n (0 < n <= 5000) and the number of toys is m (0 < m <= 5000). The coordinates of the upper-left corner and the lower-right corner of the box are (x1,y1) and (x2,y2), respectively. The following n lines contain two integers per line, Ui Li, indicating that the ends of the i-th cardboard partition is at the coordinates (Ui,y1) and (Li,y2). You may assume that the cardboard partitions do not intersect each other and that they are specified in sorted order from left to right. The next m lines contain two integers per line, Xj Yj specifying where the j-th toy has landed in the box. The order of the toy locations is random. You may assume that no toy will land exactly on a cardboard partition or outside the boundary of the box. The input is terminated by a line consisting of a single 0.

Output

The output for each problem will be one line for each separate bin in the toy box. For each bin, print its bin number, followed by a colon and one space, followed by the number of toys thrown into that bin. Bins are numbered from 0 (the leftmost bin) to n (the rightmost bin). Separate the output of different problems by a single blank line.

Sample Input

5 6 0 10 60 0
3 1
4 3
6 8
10 10
15 30
1 5
2 1
2 8
5 5
40 10
7 9
4 10 0 10 100 0
20 20
40 40
60 60
80 80
 5 10
15 10
25 10
35 10
45 10
55 10
65 10
75 10
85 10
95 10
0

Sample Output

0: 2
1: 1
2: 1
3: 1
4: 0
5: 1

0: 2
1: 2
2: 2
3: 2
4: 2

Hint

As the example illustrates, toys that fall on the boundary of the box are "in" the box.

Source

Rocky Mountain 2003

时间: 2024-10-11 05:57:24

【POJ】2318 TOYS(计算几何+暴力)的相关文章

poj 2318 TOYS(计算几何 点与线段的关系)

TOYS Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 12015   Accepted: 5792 Description Calculate the number of toys that land in each bin of a partitioned toy box. Mom and dad have a problem - their child John never puts his toys away w

POJ 2318 TOYS(计算几何)

跨产品的利用率推断点线段向左或向右,然后你可以2分钟 代码: #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N = 5005; int n, m, x1, y1, x2, y2; struct Point { int x, y; Point() {} Point(int x, int y) { this->x = x; this-&g

POJ 2318 TOYS(叉积+二分or暴力)

题目链接:POJ 2318 TOYS [写在前面]前几天跟队友分了方向,学渣开始进行计算几何的专题了,真是脑壳有点痛啊.但是我想做多了就没这么坑爹了 [题意]大体意思就是给你一个矩形,有被若干直线分成N个格子,给出M个点的坐标,问你每个点位于哪个格子中. [思路]其实就是点在凸四边形内的判断,然后就可以利用叉积的性质,当然可以用暴力枚举也可以过,但是时间复杂度有点高,最好是用二分求解.(一直觉得二分真是牛逼啊) 下面贴AC代码,用二分219MS就过了: 1 /* 2 ** POJ 2318 TO

【POJ】2318 TOYS ——计算几何+二分

TOYS Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 10281   Accepted: 4924 Description Calculate the number of toys that land in each bin of a partitioned toy box. Mom and dad have a problem - their child John never puts his toys away w

poj 2318 TOYS &amp; poj 2398 Toy Storage (叉积)

链接:poj 2318 题意:有一个矩形盒子,盒子里有一些木块线段,并且这些线段坐标是按照顺序给出的, 有n条线段,把盒子分层了n+1个区域,然后有m个玩具,这m个玩具的坐标是已知的,问最后每个区域有多少个玩具 分析:从左往右,直到判断玩具是否在线段的逆时针方向为止,这个就需要用到叉积,当然可以用二分查找优化. 叉积:已知向量a(x1,y1),向量b(x2,y2),axb=x1*y2-x2*y1, 若axb>0,a在b的逆时针方向,若axb<0,则a在b的顺时针方向 注:每组数据后要多空一行

POJ 2318 TOYS 叉积的应用

A - TOYS Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Practice POJ 2318 Appoint description:  lijunle  (2011-07-18)System Crawler  (2016-05-08) Description Calculate the number of toys that land in each b

poj 2318 TOYS(计算几何)

TOYS Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 13159   Accepted: 6357 Description Calculate the number of toys that land in each bin of a partitioned toy box. Mom and dad have a problem - their child John never puts his toys away w

TOYS - POJ 2318(计算几何,叉积判断)

题目大意:给你一个矩形的左上角和右下角的坐标,然后这个矩形有 N 个隔板分割成 N+1 个区域,下面有 M 组坐标,求出来每个区域包含的坐标数. 分析:做的第一道计算几何题目....使用叉积判断方向,然后使用二分查询找到点所在的区域. 代码如下: ============================================================================================================================ #

poj 2318 TOYS 2012-01-11

http://poj.org/problem?id=2318 ___________________________________________________ 题目大意:一个箱子用木板分成几个区间,给一些玩具的坐标,求各个区间有几个玩具. 对于每一个玩具,因为输入的区间是有序的,所以采用二分木板,判断一个玩具在哪个区间. ___________________________________________________ 1 Program Stone; 2 var i,n,m,x1,x

POJ 2318 TOYS 叉积

题意: 给出一个矩形范围,给出n条线段,这n条线段一定与矩形上下边界相交且互不相交,将矩形分成n+1个划分.给出m个玩具的坐标.求每个划分放的玩具数,玩具保证不会在线段和左右边界上. 分析: 判断点是否在两条直线中间,利用叉积,如果在两条直线间,必定会有两个叉积一个小于0,一个大于0(不能把相乘小于0作为判断条件) #include <iostream> #include <cstdio> #include <cstring> using namespace std;