POJ 2318

第一道计算几何。

二分一下用叉积来判。。看了DIS上说要INT64,就改INT64了。。。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 using namespace std;
 6 const int Max=5050;
 7
 8 struct e{
 9     int x1,x2;
10 }edge[Max];
11 struct c{
12     int x,y;
13 }cal[4];
14
15 int n,m;
16 int X1,Y1,X2,Y2;
17 int ans[Max];
18 int u,v;
19
20 void init(){
21     for(int i=0;i<=n;i++){
22         ans[i]=0;
23     }
24 }
25
26 bool in(){
27     if(u>=X1&&u<=X2&&v>=Y2&&v<=Y1)
28     return true;
29     return false;
30 }
31
32 __int64 multi(int i){
33     int j=i+1;
34     if(j==4) j=0;
35     return (__int64)(u-cal[i].x)*(__int64)(cal[j].y-cal[i].y)-(__int64)(v-cal[i].y)*(__int64)(cal[j].x-cal[i].x);
36 }
37
38 bool judge(int mid){
39     __int64 pre,now;
40     cal[0].x=edge[mid].x1; cal[0].y=Y1;
41     cal[1].x=X2; cal[1].y=Y1;
42     cal[2].x=X2; cal[2].y=Y2;
43     cal[3].x=edge[mid].x2; cal[3].y=Y2;
44     for(int i=0;i<4;i++){
45         now=multi(i);
46         if(i>0){
47             if(pre*now<0)
48             return false;
49         }
50         pre=now;
51     }
52     return true;
53 }
54
55 void slove(){
56     int low=0,high=n;
57     int anst;
58     while(low<=high){
59         int mid=(low+high)/2;
60         if(judge(mid)){
61             anst=mid; low=mid+1;
62         }
63         else high=mid-1;
64     }
65     ans[anst]++;
66 }
67
68 int main(){
69     while(scanf("%d",&n)!=EOF){
70         if(n==0) break;
71         scanf("%d%d%d%d%d",&m,&X1,&Y1,&X2,&Y2);
72         init();
73         edge[0].x1=X1,edge[0].x2=X1;
74         for(int i=1;i<=n;i++){
75             scanf("%d%d",&edge[i].x1,&edge[i].x2);
76         }
77         for(int i=0;i<m;i++){
78             scanf("%d%d",&u,&v);
79             if(in())
80                 slove();
81         }
82         for(int i=0;i<=n;i++)
83         printf("%d: %d\n",i,ans[i]);
84         printf("\n");
85     }
86     return 0;
87 }

POJ 2318,布布扣,bubuko.com

时间: 2024-10-24 10:20:05

POJ 2318的相关文章

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

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

POJ 2318/2398 叉积性质

2318 2398 题意:给出n条线将一块区域分成n+1块空间,再给出m个点,询问这些点在哪个空间里. 思路:由于只要求相对位置关系,而对具体位置不关心,那么易使用叉积性质得到相对位置关系(左侧/右侧),再因为是简单几何线段不相较,即有序分布,那么在求在哪个区间时可以先对所有线段根据x坐标排序,使用二分减少复杂度. /** @Date : 2017-07-11 11:05:59 * @FileName: POJ 2318 叉积性质.cpp * @Platform: Windows * @Auth

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 &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 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;

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

这题计算几何的部分还是比较简单的,重点是那个二分有点麻烦(大牛忽略),每次写二分自己都得用笔模拟一番,然后才能确定. 因为y1,y2是公共的,所以存储的时候线段的时候只要存储x的坐标就可以了.然后就是判断是在右边还是在左边. #include<cstdio> #include<cstring> #include<algorithm> #include<vector> using namespace std; const int N=5005; struct