【计算几何】【叉积】poj2318

开始过计算几何部分。看到一篇题目集锦,打算接下来的时间按照博客来做:https://blog.csdn.net/yang_7_46/article/details/8525631

题目链接:https://vjudge.net/problem/POJ-2318

题意:给了m个点,落在n+1个区域中,问各个区域有多少个点。

做法:就是叉积的运用,我们cross(Point o,Point a,Point b)代表向量oa和ob的叉积(代表oa到ob的夹角),叉积为正,则代表oa到ob的角为正,则点a在点b的顺时针方向(因为逆时针的角为正)。反之同理。

所以利用这条性质可以判断点在直线的左边还是右边,直接二分答案ok。

代码如下:

 1 /*************************************************************************
 2     > File Name: poj2318.cpp
 3 # File Name: poj2318.cpp
 4 # Author : xiaobuxie
 5 # QQ : 760427180
 6 # Email:760427180@qq.com
 7 # Created Time: 2019年09月17日 星期二 17时08分28秒
 8  ************************************************************************/
 9 
10 #include<iostream>
11 #include<cstdio>
12 #include<map>
13 #include<cmath>
14 #include<cstring>
15 #include<set>
16 #include<queue>
17 #include<vector>
18 #include<algorithm>
19 using namespace std;
20 typedef long long ll;
21 #define inf 0x3f3f3f3f
22 #define pq priority_queue<int,vector<int>,greater<int> >
23 ll gcd(ll a,ll b){
24     if(a<b) return gcd(b,a);
25     return b==0?a:gcd(b,a%b);
26 }
27 const int N=5e3+9;
28 struct Point{
29     int x,y;
30 }p;
31 struct Line{
32     Point s,t;
33 }L[N];
34 int ans[N];
35 int cross(Point o,Point a,Point b){
36     return (o.x-a.x)*(o.y-b.y)-(o.x-b.x)*(o.y-a.y);
37 }
38 bool judge(int x){
39     return cross(p,L[x].s,L[x].t)<=0;
40 }
41 int main(){
42     int n,m,x1,x2,y1,y2;
43     while(~scanf("%d",&n) && n){
44         memset(ans,0,sizeof(ans));
45         scanf("%d",&m);
46         scanf("%d %d %d %d",&x1,&y1,&x2,&y2);
47         for(int i=0;i<n;++i){
48             int u,l; scanf("%d %d",&u,&l);
49             L[i]=(Line){ (Point){u,y1}, (Point){l,y2}};
50         }
51         L[n]=(Line){ (Point){x2,y1}, (Point){x2,y2}};
52         while(m--){
53             int x,y;
54             scanf("%d %d",&x,&y);
55             p=(Point){x,y};
56             int l=0,r=n,res;
57             while(l<=r){
58                 int m=(l+r)>>1;
59                 if(judge(m)){
60                     res=m;
61                     r=m-1;
62                 }
63                 else l=m+1;
64             }
65             ans[res]++;
66         }
67         for(int i=0;i<=n;++i) printf("%d: %d\n",i,ans[i]);
68         printf("\n");
69     }
70     return 0;
71 }
View Code

 

posted @ 2019-09-17 17:38  小布鞋  阅读(149)  评论(0编辑  收藏  举报