POJ 2318

题目来源: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 }

 

转载于:https://www.cnblogs.com/David-Parker/p/4559081.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值