标签:
题目来源:http://poj.org/problem?id=2318
题目内容:给定一个矩形盒子(左上和右下端点的坐标),再给定n条线段,将盒子分为n+1份,之后给定m个点的坐标,对于盒子的每一段,输出内部包含的点的个数(边界上的算做盒子内)。
解法分析:核心内容有判断点与线段的关系(其实根本用不上判断点是否在多边形内的算法),二分查找。先读进数据在简单的二分查找即可。
算法如下:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 using namespace std; 5 struct Point 6 { 7 int x, y; 8 }; 9 10 struct Line 11 { 12 Point a, b; 13 } line[5005]; 14 15 int ans[5005]; //答案数组 16 17 int Multi(Point p1, Point p2, Point p0) //p2相对p1左转为正 ,叉积 18 { 19 return (p1.x - p0.x) * (p2.y - p0.y) - (p2.x - p0.x) * (p1.y - p0.y); 20 } 21 22 void BSearch(Point a, int n) 23 { 24 int l, r, mid; 25 26 l = 0; r = n-1; 27 while (l < r) 28 { 29 mid = (l + r) >> 1; // /2 30 if (Multi(a, line[mid].a, line[mid].b) > 0) //.a为上边的节点 ,若a节点在盒子中 31 l = mid + 1; //左区间推进 32 else 33 r = mid; //右区间推进 34 } 35 if (Multi(a, line[l].a, line[l].b) < 0) //判断边界 36 ans[l]++; 37 else 38 ans[l+1]++; 39 } 40 41 int main() 42 { 43 int n, m, x1, y1, x2, y2; 44 int t1, t2; 45 Point a; 46 while (scanf ("%d", &n) && n) //处理 0 结尾 数据 的 好技巧 47 { 48 scanf ("%d%d%d%d%d", &m, &x1, &y1, &x2, &y2); 49 for (int i = 0; i < n; i++) 50 { 51 scanf ("%d%d", &t1, &t2); 52 line[i].a.x = t1; //.a为上边的节点 53 line[i].a.y = y1; 54 line[i].b.x = t2; 55 line[i].b.y = y2; 56 } 57 memset(ans, 0, sizeof (ans)); 58 for (int i = 0; i < m; i++) 59 { 60 scanf ("%d%d", &a.x, &a.y); 61 BSearch(a, n); 62 } 63 for (int i = 0; i <= n; i++) 64 printf ("%d: %d\n", i, ans[i]); 65 printf("\n"); 66 } 67 return 0; 68 }
标签:
原文地址:http://www.cnblogs.com/David-Parker/p/4559081.html