POJ 2318--TOYS(二分找点,叉积判断方向)

TOYS

Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 17974   Accepted: 8539

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

  1. 题意:给n条边,划分成n+1个区域,再给定m个点坐标,点不会落在边界上和区域外,问每个区域中各自存在多少个点
  2. 代码如下  

     1 #include<iostream>
     2 #include<cstring>
     3 #include<string>
     4 #include<algorithm>
     5 #include<vector>
     6 #include<stack>
     7 #include<bitset>
     8 #include<cstdio>
     9 #include<cstdlib>
    10 #include<cmath>
    11 #include<set>
    12 #include<list>
    13 #include<deque>
    14 #include<map>
    15 #include<queue>
    16 using namespace std;
    17 const int MAX = 5005;
    18
    19 typedef struct point {
    20     int x;
    21     int y;
    22 }point;
    23 typedef struct value {
    24     point start;
    25     point end;
    26 }v;
    27 v edge[MAX];
    28 int sum[MAX];
    29 int n, m, x1, y11, x2, y2, flag = 1;
    30 point tp;
    31 int Xj, Yj;
    32 int multi(point p1, point p2, point p0) {  //判断p1p0和p2p0的关系,<0,p1p0在p2p0的逆时针方向
    33     return (p1.x - p0.x)*(p2.y - p0.y) - (p2.x - p0.x)*(p1.y - p0.y);
    34 }
    35 void inset(point p) {
    36     int low = 0, high = n;
    37     while (low <= high) {
    38         int mid = (high + low) / 2;
    39         if (multi(p, edge[mid].start, edge[mid].end) < 0)    /*点p1在边的左侧*/
    40             high = mid - 1;
    41         else    //点p在边的右侧
    42             low = mid + 1;
    43     }
    44     if (multi(p, edge[low-1].start, edge[low-1].end) < 0 )
    45         sum[low-1]++;
    46     else
    47         sum[low]++;
    48 }
    49 int main() {
    50     while (~scanf("%d", &n) && n) {
    51         memset(sum, 0, sizeof(sum));
    52         if (flag == 1)flag++;
    53         else printf("\n");
    54         scanf("%d%d%d%d%d", &m, &x1, &y11, &x2, &y2);
    55         int Ui, Li;
    56         for (int i = 0; i < n; i++) {
    57             scanf("%d%d", &Ui, &Li);
    58             edge[i].start.x = Ui;
    59             edge[i].start.y = y11;
    60             edge[i].end.x = Li;
    61             edge[i].end.y = y2;
    62         }
    63         edge[n].start.x = x2;
    64         edge[n].start.y = y11;
    65         edge[n].end.x = x2;
    66         edge[n].end.y = y2;
    67         for (int j = 0; j < m; j++) {
    68             scanf("%d%d", &Xj, &Yj);
    69             tp.x = Xj;
    70             tp.y = Yj;
    71             inset(tp);
    72         }
    73         for (int i = 0; i <= n; i++)
    74             printf("%d: %d\n", i, sum[i]);
    75     }
    76     return 0;
    77 }

  3. Experience: 前面点的构造写成

    1 edge[i].start = { Ui,y11 };
    2 edge[i].end = { Li,y2 };

    当发现这个错误的时候,我自己都被自己蠢哭了,Wa了2页,一直以为是叉积方向搞错了,原来不是ORZ

  4. 这个是我真正意义上第一道计算几何,mark一下。

原文地址:https://www.cnblogs.com/FlyerBird/p/9265941.html

时间: 2024-11-13 06:59:13

POJ 2318--TOYS(二分找点,叉积判断方向)的相关文章

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

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

POJ 2318 TOYS(点与直线的关系 叉积&amp;&amp;二分)

题目链接 题意: 给定一个矩形,n个线段将矩形分成n+1个区间,m个点,问这些点的分布. 题解: 思路就是叉积加二分,利用叉积判断点与直线的距离,二分搜索区间. 代码: 最近整理了STL的一些模板,发现真是好用啊orz,为啥以前没发现呢,可能是比较懒吧-.- #include <stdio.h> #include <string.h> #include <cmath> #include <iostream> #include <queue> #i

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 Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 10425 Accepted: 5002 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

POJ 2318 TOYS 利用叉积判断点在线段的那一侧

题意:给定n(<=5000)条线段,把一个矩阵分成了n+1分了,有m个玩具,放在为位置是(x,y).现在要问第几个位置上有多少个玩具. 思路:叉积,线段p1p2,记玩具为p0,那么如果(p1p2 ^ p1p0) (记得不能搞反顺序,不同的),如果他们的叉积是小于0,那么就是在线段的左边,否则右边.所以,可以用二分找,如果在mid的左边,end=mid-1 否则begin=mid+1.结束的begin,就是第一条在点右边的线段 #include <cstdio> #include <

POJ 2318 TOYS【叉积+二分】

今天开始学习计算几何,百度了两篇文章,与君共勉! 计算几何入门题推荐 计算几何基础知识 题意:有一个盒子,被n块木板分成n+1个区域,每个木板从左到右出现,并且不交叉. 有m个玩具(可以看成点)放在这个盒子里,问每个区域分别有多少个玩具. 思路:首先,用叉积判断玩具是否在木板的左边,再用二分找到符合的最右边的木板,该木板答案加一. #include<stdio.h> #include<string.h> struct point{ int x,y; point(){} point(

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: 11078   Accepted: 5312 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

向量的叉积 POJ 2318 TOYS

题目大意:给定一个盒子的左上角和右下角坐标,然后给n条线,可以将盒子分成n+1个部分,再给m个点,问每个区域内有多少各点 这个题用到关键的一步就是向量的叉积,假设一个点m在 由abcd围成的四边形区域内,那么向量ab, bc, cd, da和点的关系就是,点都在他们的同一侧,我是按照逆时针来算的,所以只需要判断叉积是否小于0就行了.还有一个问题就是这个题要求时间是2s,所以直接找,不用二分也能过,不过超过1s了,最好还是二分来做,二分时间170ms,二分的时候要把最左边的一条边和最右边的一条边都

poj 2318 TOYS(判点与线段的关系)

TOYS Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 11643   Accepted: 5616 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