首页 > 代码库 > POJ 2318 TOYS(叉积+二分or暴力)
POJ 2318 TOYS(叉积+二分or暴力)
题目链接:POJ 2318 TOYS
【写在前面】前几天跟队友分了方向,学渣开始进行计算几何的专题了,真是脑壳有点痛啊。但是我想做多了就没这么坑爹了
【题意】大体意思就是给你一个矩形,有被若干直线分成N个格子,给出M个点的坐标,问你每个点位于哪个格子中。
【思路】其实就是点在凸四边形内的判断,然后就可以利用叉积的性质,当然可以用暴力枚举也可以过,但是时间复杂度有点高,最好是用二分求解。(一直觉得二分真是牛逼啊)
下面贴AC代码,用二分219MS就过了:
1 /* 2 ** POJ 2318 TOYS 3 ** Created by Rayn @@ 2014/05/04 4 */ 5 #include <cstdio> 6 #include <cstring> 7 #include <algorithm> 8 using namespace std; 9 const int MAX = 5010; 10 const int INF = 0x3f3f3f3f; 11 12 struct Point { 13 double x, y; 14 Point(double a=0, double b=0): x(a), y(b) {} 15 } dot[MAX]; 16 17 double up[MAX], low[MAX]; 18 int ans[MAX]; 19 20 double Cross(Point A, Point B, Point C) 21 { 22 return (C.x-A.x)*(B.y-A.y)-(B.x-A.x)*(C.y-A.y); 23 } 24 int main() 25 { 26 #ifdef _Rayn 27 freopen("in.txt", "r", stdin); 28 #endif 29 30 int n, m, first = 1; 31 double x1, y1, x2, y2; 32 33 while(scanf("%d", &n) != EOF && n) 34 { 35 if(!first) 36 printf("\n"); 37 first = 0; 38 39 scanf("%d%lf%lf%lf%lf", &m, &x1, &y1, &x2, &y2); 40 for(int i=0; i<n; ++i) 41 { 42 scanf("%lf%lf", &up[i], &low[i]); 43 } 44 up[n] = low[n] = x2; //最后一条,矩形的右边(x2,y1),(x2,y2),方便判断; 45 46 //强大的二分 47 memset(ans, 0, sizeof(ans)); 48 for(int i=0; i<m; ++i) 49 { 50 scanf("%lf%lf", &dot[i].x, &dot[i].y); 51 int left = 0, right = n, mid = 0; 52 while(left <= right) 53 { 54 mid = (left + right) / 2; 55 Point b(low[mid], y2), c(up[mid], y1); 56 if(Cross(dot[i], b, c) > 0) 57 left = mid + 1; 58 else 59 right = mid - 1; 60 } 61 ans[left]++; 62 } 63 for(int i=0; i<=n; ++i) 64 printf("%d: %d\n", i, ans[i]); 65 } 66 return 0; 67 }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。