题目大意:给你一个矩形的左上角和右下角的坐标,然后这个矩形有 N 个隔板分割成 N+1 个区域,下面有 M 组坐标,求出来每个区域包含的坐标数。

 
分析:做的第一道计算几何题目....使用叉积判断方向,然后使用二分查询找到点所在的区域。
 
代码如下:
============================================================================================================================
  1. #include<stdio.h>
  2. #include<math.h>
  3. using namespace std;
  4.  
  5. const int MAXN = 5e3+;
  6. const double PI = acos(-1.0);
  7.  
  8. struct point
  9. {
  10. double x, y;
  11.  
  12. point(int x=, int y=):x(x), y(y){}
  13. };
  14. struct Vector
  15. {
  16. point a, b;
  17.  
  18. void InIt(point t1, point t2){a=t1, b=t2;}
  19. double operator * (const point &p) const
  20. {
  21. return (p.x-b.x)*(a.y-b.y) - (p.y-b.y)*(a.x-b.x);
  22. }
  23. };
  24.  
  25. Vector line[MAXN];
  26.  
  27. int Find(int N, point a)
  28. {
  29. int L=, R=N;
  30.  
  31. while(L <= R)
  32. {
  33. int Mid = (L+R) >> ;
  34.  
  35. if(line[Mid] * a < )
  36. R = Mid - ;
  37. else
  38. L = Mid + ;
  39. }
  40.  
  41. return R;
  42. }
  43.  
  44. int main()
  45. {
  46. int M, N;
  47. double x1, x2, y1, y2, ui, li;
  48.  
  49. while(scanf("%d", &N) != EOF && N)
  50. {
  51. scanf("%d%lf%lf%lf%lf", &M, &x1, &y1, &x2, &y2);
  52.  
  53. int ans[MAXN]={};
  54.  
  55. line[].InIt(point(x1, y1), point(x1, y2));
  56. for(int i=; i<=N; i++)
  57. {
  58. scanf("%lf%lf", &ui, &li);
  59. line[i].InIt(point(ui, y1), point(li, y2));
  60. }
  61. while(M--)
  62. {
  63. scanf("%lf%lf", &ui, &li);
  64. int i = Find(N, point(ui, li));
  65.  
  66. ans[i] += ;
  67. }
  68.  
  69. for(int i=; i<=N; i++)
  70. printf("%d: %d\n", i, ans[i]);
  71. printf("\n");
  72. }
  73.  
  74. return ;
  75. }

重写...

  1. #include<math.h>
  2. #include<stdio.h>
  3. #include<vector>
  4. #include<iostream>
  5. #include<algorithm>
  6. using namespace std;
  7.  
  8. const double EPS = 1e-;
  9. const int maxn = ;
  10.  
  11. int SIGN(const double &val)
  12. {///整数返回1,负数返回-1, 0返回0
  13. if(val > EPS)return ;
  14. if(fabs(val) < EPS)return ;
  15. return -;
  16. }
  17.  
  18. class Point
  19. {
  20. public:
  21. Point(double x, double y): x(x), y(y){}
  22. Point operator- (const Point& other)const
  23. {///重载减号
  24. return Point((x-other.x), (y - other.y));
  25. }
  26. double operator^(const Point& other)const
  27. {///重载异或,定义叉积的运算
  28. return (x*other.y) - (y*other.x);
  29. }
  30. public:
  31. double x, y;
  32. };
  33.  
  34. class Segment
  35. {
  36. public:
  37. Segment(Point S, Point E) : S(S), E(E){}
  38. int Mul(Point& other) const
  39. {///用差乘判断点在线段的方向
  40. return SIGN( (E-S)^(other-S) );
  41. }
  42. public:
  43. Point S, E;
  44. };
  45.  
  46. class SetSegment
  47. {///定义一个线段的集合,有很多线段构成
  48. public:
  49. void Insert(const Segment& other)
  50. {///插入一个线段
  51. segs.push_back(other);
  52. }
  53. unsigned int Find(Point p)
  54. {///查找点p靠近的最左边的线段的下标
  55. unsigned int L=, R=segs.size()-, M;
  56.  
  57. while(L <= R)
  58. {
  59. M = (L+R) / ;
  60. Segment tmp = segs[M];
  61. if(tmp.Mul(p) == -)
  62. R = M-;
  63. else
  64. L = M+;
  65. }
  66.  
  67. return R;
  68. }
  69. public:
  70. vector<Segment> segs;
  71. };
  72. int main()
  73. {
  74. int N, M;
  75. double x1, x2, y1, y2, Ui, Li;
  76.  
  77. while(scanf("%d", &N) != EOF && N)
  78. {
  79. scanf("%d%lf%lf%lf%lf", &M, &x1, &y1, &x2, &y2);
  80.  
  81. SetSegment ss;
  82.  
  83. ss.Insert(Segment(Point(x1, y1), Point(x1, y2)));
  84. for(int i=; i<N; i++)
  85. {
  86. scanf("%lf%lf", &Ui, &Li);
  87. ss.Insert(Segment(Point(Ui, y1), Point(Li, y2)));
  88. }
  89.  
  90. int ans[maxn] = {};
  91.  
  92. while(M--)
  93. {
  94. scanf("%lf%lf", &x1, &y1);
  95.  
  96. int index = ss.Find(Point(x1, y1));
  97. ans[index] += ;
  98. }
  99.  
  100. for(int i=; i<=N; i++)
  101. printf("%d: %d\n", i, ans[i]);
  102. printf("\n");
  103. }
  104.  
  105. return ;
  106. }

TOYS - POJ 2318(计算几何,叉积判断)的更多相关文章

  1. TOYS POJ 2318 计算几何 叉乘的应用

    Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 15060   Accepted: 7270 Description Calc ...

  2. POJ 2318/2398 叉积性质

    2318 2398 题意:给出n条线将一块区域分成n+1块空间,再给出m个点,询问这些点在哪个空间里. 思路:由于只要求相对位置关系,而对具体位置不关心,那么易使用叉积性质得到相对位置关系(左侧/右侧 ...

  3. POJ 2398--Toy Storage(叉积判断,二分找点,点排序)

    Toy Storage Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6534   Accepted: 3905 Descr ...

  4. POJ 2318 TOYS(叉积+二分)

    题目传送门:POJ 2318 TOYS Description Calculate the number of toys that land in each bin of a partitioned ...

  5. 向量的叉积 POJ 2318 TOYS & POJ 2398 Toy Storage

    POJ 2318: 题目大意:给定一个盒子的左上角和右下角坐标,然后给n条线,可以将盒子分成n+1个部分,再给m个点,问每个区域内有多少各点 这个题用到关键的一步就是向量的叉积,假设一个点m在 由ab ...

  6. POJ 2318 TOYS【叉积+二分】

    今天开始学习计算几何,百度了两篇文章,与君共勉! 计算几何入门题推荐 计算几何基础知识 题意:有一个盒子,被n块木板分成n+1个区域,每个木板从左到右出现,并且不交叉. 有m个玩具(可以看成点)放在这 ...

  7. POJ 2398 Toy Storage(计算几何,叉积判断点和线段的关系)

    Toy Storage Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 3146   Accepted: 1798 Descr ...

  8. POJ 2318 TOYS (叉积+二分)

    题目: Description Calculate the number of toys that land in each bin of a partitioned toy box. Mom and ...

  9. poj 2318(叉积判断点在线段的哪一侧)

    TOYS Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 13120   Accepted: 6334 Description ...

随机推荐

  1. PC110302/UVA10010

    下周开始就省选了,ACM的日子在今年内应该就会结束了,大三了,最后一次机会了,小小感伤一下-- 今天广州下大雨,心情怪怪的,感觉码不出质量高的,又很久没做过PC了,就刷刷水题吧. 老实说Program ...

  2. iframe中的各种跳转方法(转)

    一.背景A,B,C,D都是jsp,D是C的iframe,C是B的iframe,B是A的iframe,在D中跳转页面的写法区别如下. 二.JS跳转window.location.href.locatio ...

  3. 获取动态SQL查询语句返回值(sp_executesql)

    在写存储过程时经常会遇到需要拼接SQL语句的情况,一般情况下仅仅是为了执行拼接后的语句使用exec(@sql)即可. 而今天的一个存储过程却需要获取动态SQL的查询结果. 需求描述:在某表中根据Id值 ...

  4. CentOS6.3安装VBoxAdditions

    yum update kernel yum install kernel-devel gcc gcc-c++

  5. jquery mobile基本结构搭建

    官网:http://jquerymobile.com/ 基本结构:

  6. sql知识

    SQL 基本知识 SQL Server 是Microsoft 公司推出的关系型数据库管理系统.具有使用方便可伸缩性好与相关软件集成程度高等优点,可跨越从运行Microsoft Windows 98 的 ...

  7. 自己使用Jquery封装各种功能分享

    自己使用Jquery封装各种功能分享: 左右滚动图片 瀑布流 流动显示列表 广告切换 头像切换And广告切换 获取搜索引擎的来源关键字 上面列表中展示的功能都是使用jquery进行封装实现的,希望大家 ...

  8. 我的接口框架---框架函数文件common.php

    <?php defined('JDHU') OR die('no allow access'); /** * 加载配置文件 */ function &get_config($replac ...

  9. ubuntu使用github

    Ubuntu下安装Git Ubuntu12.04 LTS默认是已经安装Git的,可以使用 git --version 测试是否安装.如果没有安装,使用命令: sudo apt-get install ...

  10. directUI

    MFC界面开发中,习惯了使用控件,亦或者是自绘制控件来美化界面,但操作起来繁琐,还不太美观.DirectUI的出现,对于界面开发,给了我们一个新的选择,目前很多公司使用了该技术对其产品进行了美化,效果 ...