题目链接:http://poj.org/problem?id=2318

题面:

                                 TOYS
Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 17413   Accepted: 8300

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.
 
思路:对于每一条分界线,首先进行排序(根据他的上面的x排和下面的排都是可以的),然后标号从0到n-1。然后问题就转换为现在访问的点会在哪条分界线的左端,若落在第i条直线的左端,那么它也就落在区域i内,确定所属区域后直接return。在最后面对第n个区域进行处理前面没被return的点。对于本题的关键就是处理点与直线的位置关系,而这个用向量的叉积进行处理即可。
代码实现如下:
 #include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; const int maxn = 5e3 + ;
int n, m, x1, x2, y1, y2;
int num[maxn]; struct node {
int x, y;
bool operator < (const node &b) const {
return x < b.x;
}
} P[maxn], L[maxn], nw, nxt; //P储存所访问的点(其实也可以不用数组的),L储存直线(对于直线此处的x为上方的x,y为下方的y); double dot(node a, node b) {
return (a.x * b.y - a.y * b.x);
} bool check(node p, node pp) {
nw.x = p.x - pp.y, nw.y = p.y - y2, nxt.x = pp.x - pp.y, nxt.y = y1 - y2;
if( dot(nw, nxt) < ) { //为负则说明当前访问的点在该直线的左端;
return true;
} else
return false;
} void Throw(node p) {
for(int i = ; i < n; i++) {
if(check(p, L[i])) {
num[i]++;
return;
}
}
num[n]++;
return;
} int main() {
//freopen("in.txt", "r", stdin);
while(~scanf("%d", &n) && n) {
scanf("%d%d%d%d%d", &m, &x1, &y1, &x2, &y2);
memset(num, , sizeof(num));
for(int i = ; i < n; i++) {
scanf("%d%d", &L[i].x, &L[i].y);
}
sort(L, L + n);
for(int i = ; i < m; i++) {
scanf("%d%d", &P[i].x, &P[i].y);
Throw(P[i]);
}
for(int i = ; i <= n; i++) {
printf("%d: %d\n", i, num[i]);
}
printf("\n");
}
return ;
}

18年10月6日更新:

前面的代码是以前看题解写的,今天再做一次,发现就是求一个叉积的事。

思路:首先将所有直线用结构体存起来,按照u排序,若u相同则按照l排序;这样就使得线段是有序的,第1条线段左边是0号区域,第2条左边是1号……第n条左边是n-1号,右边是n号。将每个点依次与这些直线求叉积,若该点在第i条直线的顺时针方向(也就是叉积为正数),那么点必落在第i-1号区域;若与所有直线的叉积都为负数则落在第n号区域。

代码实现如下:

 #include <set>
#include <map>
#include <deque>
#include <ctime>
#include <stack>
#include <cmath>
#include <queue>
#include <string>
#include <cstdio>
#include <vector>
#include <iomanip>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std; typedef long long LL;
typedef pair<LL, LL> pll;
typedef pair<LL, int> pli;
typedef pair<int, int> pii;
typedef unsigned long long uLL; #define lson rt<<1
#define rson rt<<1|1
#define name2str(name)(#name)
#define bug printf("**********\n");
#define IO ios::sync_with_stdio(false);
#define debug(x) cout<<#x<<"=["<<x<<"]"<<endl;
#define FIN freopen("/home/dillonh/CLionProjects/in.txt","r",stdin); const double eps = 1e-;
const int maxn = + ;
const int inf = 0x3f3f3f3f;
const double pi = acos(-1.0);
const LL INF = 0x3f3f3f3f3f3f3f3fLL; int n, m, x1, yy, x2, y2, x, y;
int cnt[maxn]; struct Line {
int l, r;
bool operator < (const Line& x) const {
return l == x.l ? r < x.r : l < x.l;
}
}L[maxn]; int cross(int x1, int y1, int x2, int y2, int x3, int y3) {
return (x2 - x1) * (y3 - y1) - (y2 - y1) * (x3 - x1);
} int main() {
#ifndef ONLINE_JUDGE
FIN;
#endif
int vis = ;
while(~scanf("%d", &n) && n) {
if(vis) printf("\n");
vis = ;
scanf("%d%d%d%d%d", &m, &x1, &yy, &x2, &y2);
for(int i = ; i <= n; i++) {
scanf("%d%d", &L[i].l, &L[i].r);
}
sort(L + , L + n + );
memset(cnt, , sizeof(cnt));
for(int i = ; i <= m; i++) {
scanf("%d%d", &x, &y);
int flag = ;
for(int j = ; j <= n; j++) {
if(cross(L[j].r, y2, L[j].l, yy, x, y) > ) {
flag = ;
cnt[j-]++;
break;
}
}
if(!flag) cnt[n]++;
}
for(int i = ; i <= n; i++) {
printf("%d: %d\n", i, cnt[i]);
}
}
return ;
}

TOYS(计算几何基础+点与直线的位置关系)的更多相关文章

  1. Intersecting Lines (计算几何基础+判断两直线的位置关系)

    题目链接:http://poj.org/problem?id=1269 题面: Description We all know that a pair of distinct points on a ...

  2. poj 1269 判断直线的位置关系

    题目链接 题意 判断两条直线的位置关系,重合/平行/相交(求交点). 直线以其上两点的形式给出(点坐标为整点). 思路 写出直线的一般式方程(用\(gcd\)化为最简), 计算\(\begin{vma ...

  3. Intersecting Lines---poj1269(求两直线的位置关系)

    题目链接:http://poj.org/problem?id=1269 题意:给你两条直线上的任意不同的两点,然后求两条直线的位置关系,如果相交于一点输出该点坐标; #include<iostr ...

  4. 判断两条直线的位置关系 POJ 1269 Intersecting Lines

    两条直线可能有三种关系:1.共线     2.平行(不包括共线)    3.相交. 那给定两条直线怎么判断他们的位置关系呢.还是用到向量的叉积 例题:POJ 1269 题意:这道题是给定四个点p1, ...

  5. POJ 1269 /// 判断两条直线的位置关系

    题目大意: t个测试用例 每次给出一对直线的两点 判断直线的相对关系 平行输出NODE 重合输出LINE 相交输出POINT和交点坐标 1.直线平行 两向量叉积为0 2.求两直线ab与cd交点 设直线 ...

  6. POJ 2318 - TOYS - [计算几何基础题]

    题目链接:http://poj.org/problem?id=2318 Time Limit: 2000MS Memory Limit: 65536K Description Calculate th ...

  7. POJ 2318 /// 判断点与直线的位置关系

    题目大意: n块玩具箱隔板 m个玩具落地点 给定玩具箱的左上和右下两个端点 接下来给定n块隔板的上点的x和下点的x(因为y就是玩具箱的上下边缘) 接下来给定m个玩具落地点 输出n+1个区域各有的玩具数 ...

  8. POJ 2398 map /// 判断点与直线的位置关系

    题目大意: poj2318改个输出 输出 a: b 即有a个玩具的格子有b个 可以先看下poj2318的报告 用map就很方便 #include <cstdio> #include < ...

  9. 【kuangbin专题】计算几何基础

    1.poj2318 TOYS 传送:http://poj.org/problem?id=2318 题意:有m个点落在n+1个区域内.问落在每个区域的个数. 分析:二分查找落在哪个区域内.叉积判断点与线 ...

随机推荐

  1. iOS-cocoapods使用方法

    1.CocoaPods的安装及使用: http://code4app.com/article/cocoapods-install-usage http://objccn.io/issue-6-4/ h ...

  2. bwapp之xss(blog)

    存储型XSS,持久化,代码是存储在服务器中的,如在个人信息或发表文章等地方,加入代码,如果没有过滤或过滤不严,那么这些代码将储存到服务器中,用户访问该页面的时候触发代码执行.这种XSS比较危险,容易造 ...

  3. 【Linux】- CentOS 防火墙iptables和firewall

    1 iptables防火墙 1.1 基本操作 # 查看防火墙状态 service iptables status   # 停止防火墙 service iptables stop   # 启动防火墙 s ...

  4. phpmyadmin打开空白

    本地phpstudy环境,打开 phpmyadmin,登陆之后,显示空白页面. 解决办法:切换为 低版本的php版本,正常登陆.

  5. [STAThread] 作用

    [STAThread]是一种线程模型,用在程序的入口方法上(在C#和VB.NET里是Main()方法),来指定当前线程的ApartmentState 是STA. [STAThread]是声明开始线程用 ...

  6. mysql(二) 慢查询分析(一)

    如下表结构: CREATE TABLE `trade_order` ( `order_id` ) unsigned NOT NULL AUTO_INCREMENT COMMENT '订单编号', `t ...

  7. 反向传播算法 Backpropagation Algorithm

    假设我们有一个固定样本集,它包含 个样例.我们可以用批量梯度下降法来求解神经网络.具体来讲,对于单个样例(x,y),其代价函数为:这是一个(二分之一的)方差代价函数.给定一个包含 个样例的数据集,我们 ...

  8. 【bzoj2060】[Usaco2010 Nov]Visiting Cows拜访奶牛 树形dp

    题目描述 经过了几周的辛苦工作,贝茜终于迎来了一个假期.作为奶牛群中最会社交的牛,她希望去拜访N(1<=N<=50000)个朋友.这些朋友被标号为1..N.这些奶牛有一个不同寻常的交通系统 ...

  9. [牛客Wannafly挑战赛27D]绿魔法师

    description newcoder 给你一个空的可重集合\(S\). \(n\)次操作,每次操作给出\(x\),\(k\),\(p\),执行以下操作: \(opt\ 1\):在S中加入x. \( ...

  10. hihoCoder#1698 : 假期计划 组合数

    题面:hihoCoder#1698 : 假期计划  组合数 题解: 题目要求是有序的排列,因此我们可以在一开始就乘上A!*B!然后在把这个序列划分成很多段. 这样的话由于乘了阶乘,所以所有排列我们都已 ...