http://poj.org/problem?id=2398

题意大概是说将一个盒子用n个board分成n+1 部分

然后往里面放toy,给定盒子,board,和toy的坐标

问所有的toy放完后,有多少部分中有t个toy;

简单计算几何

需要判断的是点和直线的关系.

判断 某一点在直线左右侧

左右方向是相对前进方向的,只要指定了前进方向就可以知道左右(比如指定前进方向是从直线的起点到终点).判断点在直线的左侧还是右侧是计算几何里面的一个最基本算法.使用矢量来判断. 
定义:平面上的三点P1(x1,y1),P2(x2,y2),P3(x3,y3)的面积量:


S(P1,P2,P3)=|y1 y2 y3|= (x1-x3)*(y2-y3)-(y1-y3)*(x2-x3)

当P1P2P3逆时针时S为正的,当P1P2P3顺时针时S为负的。

令矢量的起点为A,终点为B,判断的点为C, 
如果S(A,B,C)为正数,则C在矢量AB的左侧; 
如果S(A,B,C)为负数,则C在矢量AB的右侧; 
如果S(A,B,C)为0,则C在直线AB上。

/*************************************************************************> File Name: code/2015summer/0718/B.cpp> Author: 111qqz> Email: rkz2013@126.com > Created Time: 2015年07月18日 星期六 11时58分14秒************************************************************************/
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<map>
#include<set>
#include<queue>
#include<vector>
#include<stack>
using namespace std;
#define REP(i, n) for (int i=0;i<int(n);++i)
typedef long long LL;
typedef unsigned long long ULL;
const int N=2E3+5;
struct node
{int x,y;
};
struct node rec,rec2;
struct node par[N],par2[N];
struct node toy[N];
int ans[N],cnt[N];
int n,m;
bool judge(node p1,node p2,node p3) //判断点是否在直线的[右侧!!]
{int s = (p1.x-p3.x)*(p2.y-p3.y)-(p1.y-p3.y)*(p2.x-p3.x);if (s>0) return false;if (s<0) return true;
}
bool cmp(node a,node b)
{if (a.x<b.x) return true;if (a.x==b.x&&a.y<b.y) return true;return false;
}
int main()
{while (scanf("%d",&n)!=EOF&&n){memset(ans,0,sizeof(ans));memset(par,0,sizeof(par));memset(par2,0,sizeof(par2));memset(toy,0,sizeof(toy));cin>>m>>rec.x>>rec.y>>rec2.x>>rec2.y;for ( int i = 1 ;  i <= n ; i++){cin>>par[i].x>>par2[i].x;par[i].y=rec.y;par2[i].y=rec2.y;}for ( int i = 1 ; i <= n-1 ; i++){for ( int j = i+1 ; j <= n ; j++){if (par[i].x>par[j].x){swap(par[i].x,par[j].x);//  swap(par[i].y,par[j].y);
              swap(par2[i].x,par2[j].x);//   swap(par2[i].y,par2[j].y);
            }}}
//      for ( int i = 1 ;  i <= n ; i++)
//        cout<<par[i].x<<endl;for ( int i = 1 ;  i <= m ; i++ ){cin>>toy[i].x>>toy[i].y;}int p;sort(toy+1,toy+m+1,cmp);  //如果第i个娃娃在第k个分划中,那么排序后第i+1个娃娃至少在第k个分划中....(某大神说过,顺手就能写的优化顺手
//      for ( int i = 1 ; i <= m ; i++)  cout<<"x[i]:"<<toy[i].x<<" y[i]:"<<toy[i].y<<endl;for ( int i = 1 ; i  <= m ;  i++) {p = n + 1;  //如果在所有board的右侧,那么一定是在最后一个分划中(n个板子形成n+1个分划)bool ok=false;for ( int j = 1 ; j  <= n ; j++){ok=judge(par2[j],par[j],toy[i]);if (!ok){//      cout<<"i:"<<i<<" j:"<<j<<" "<<par2[j].x<<" "<<par2[j].y<<" "<<par[j].x<<" "<<par[j].y<<endl;p = j;break;//    cout<< "hhhhhh"<<"I:"<<i<<" j:"<<j<<endl;
            }}ans[p]++;}cout<<"Box"<<endl;memset(cnt,0,sizeof(cnt));for ( int i = 1 ; i <= n+1 ; i++){if (ans[i]==0) continue;cnt[ans[i]]++;//    printf("%d: %d\n",i,ans[i]);
      }for ( int i = 1 ; i <= m ;  i++){if (cnt[i]==0) continue;printf("%d: %d\n",i,cnt[i]);}}return 0;
}

转载于:https://www.cnblogs.com/111qqz/p/4665640.html

poj 2398 Toy Storage (计算几何,判断点和线段关系)相关推荐

  1. poj 2318 TOYS amp; poj 2398 Toy Storage (叉积)

    链接:poj 2318 题意:有一个矩形盒子,盒子里有一些木块线段.而且这些线段坐标是依照顺序给出的. 有n条线段,把盒子分层了n+1个区域,然后有m个玩具.这m个玩具的坐标是已知的,问最后每一个区域 ...

  2. 计算区域中有t 个点的 区域有多少个+计算几何 + 叉乘+sort+ 二分 + map poj 2398 Toy Storage...

    题目来源:http://poj.org/problem?id=2398 分析: 计算区域中有t 个点的 区域有多少个. #include <cstdlib> #include <cs ...

  3. POJ 2398 Toy Storage

    这道题和POJ 2318几乎是一样的. 区别就是输入中坐标不给排序了,=_=|| 输出变成了,有多少个区域中有t个点. 1 #include <cstdio> 2 #include < ...

  4. 计算几何-判断两条线段是否相交

    原理:如果两条线段相交,那么必须跨立,就是以一条线段为标准,另一条线段的两端点一定在这条线段的两段 也就是说a b两点在线段cd的两端,c d两点在线段ab的两端 struct point() {do ...

  5. java判断线段是否相交函数_计算几何-判断线段是否相交

    计算几何-判断线段相交 判断两线段是否相交: 快速排斥 跨立实验(这两个词也是我看博客的时候看到的,觉得挺高大上的就拿过来用了,哈哈哈) 1. 快速排斥:就是初步的判断一下,两条线段是不是相交,以两条 ...

  6. mysql查询表字段是否存在_Mysql判断表字段或索引是否存在

    判断字段是否存在: DROP PROCEDURE IF EXISTS schema_change; DELIMITER // CREATE PROCEDURE schema_change() BEGI ...

  7. mysql字段是否存在_Mysql判断表字段或索引是否存在

    判断字段是否存在: DROP PROCEDURE IF EXISTS schema_change; DELIMITER // CREATE PROCEDURE schema_change() BEGI ...

  8. 如何判断两条线段是否相交

    本篇是在 [C++笔记]如何判断2个线段相交 的基础上加上自己的理解和实践总结出的判断两线段是否相交的方法. 判断两条线段是否相交 先附上判断函数 bool judge(int Ax1,int Ay1 ...

  9. 判断两条线段是否相交 java_判断两个线段是否相交02

    写在前面 在其他博客中看到这方面的知识,很多都是重复,并且说的总是云里雾里的,所以这里我就自己总结一下这种问题如何求解,判断两个线段是否相交在前面我们提到了会用到叉积的一点知识,那么这里就来详细说一下 ...

最新文章

  1. Oracle --获取绑定变量的值.
  2. 【软件-软件设计师】操作系统知识架构图
  3. 1.3编程基础之算术表达式与顺序执行 11 计算浮点数相除的余数
  4. (王道408考研操作系统)第五章输入/输出(I/O)管理-第一节2:I/O控制器
  5. lua是编译成c语言再执行嘛,go_lua_c: 使用go编译lua脚本为字节码,通过网络传给c,通过c执行lua脚本。...
  6. 将json转为map的两种方式及前后端开发json Api设计规范总结
  7. python中变量的生命周期
  8. linux 如何看图软件,深度看图(linux看图软件) v1.2 官方最新版
  9. 恶意软件家族分类 单模型方案总结
  10. 照片文件与计算机系统,如何备份电脑中的照片等重要文件
  11. 最简单的方式实现竖排文字显示
  12. Groups CodeForces - 1598B
  13. 吃的很晚仍然能减肥不?
  14. class AdamWeightDecayOptimizer(tf.train.Optimizer): AttributeError: module ‘tensorflow._api.v2.tra
  15. 临时链接转为永久链接的三种方法
  16. 微信公众号采集 php,如何采集微信公众号历史消息页
  17. Notion for Mac(免费办公笔记软件)
  18. 挖掘应用型创新人才 第六届大学生RDMA编程挑战赛正式启幕
  19. 身价过亿的灵仙子说你IIC没写完也发?
  20. 关于 身体 不适的 English

热门文章

  1. java判断当前时间距离第二天凌晨的秒数
  2. 国开计算机应用基础中考答案,国开计算机应用基础模块4PowerPoint2010电子演示文稿系统答案...
  3. 硬件知识:U盘缩水是怎么回事,如何恢复U盘真实容量?
  4. 如何快速清空Linux中的大文件?
  5. 硬件:电脑基础进阶必学知识,详解电脑主板跳线!
  6. GitHub:一份玩转 GitHub 的秘诀,值得收藏!
  7. SQL数据库面试题以及答案!
  8. 程序员的二十句励志名言,看看你最喜欢哪句?
  9. 嵌入式C语言基础(三)
  10. Python脚本模拟登录网页之CSDN篇