TOYS(计算几何-入门)

题目

‘^’代表叉乘

‘?’代表点乘

点积:a?b=ax*bx+ay*by

叉积:a^b=ax*by-bx*ay

有了这些,代码就呼之欲出了。

首先read(线段)

然后read(点)

发现满足二分性(点A一定在前t条线后,在后n-t条线前)

于是,二分优化查找

O(mlogn)

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <vector>
#include <cmath>
#include <queue>
#include <map>
#include <set>
using namespace std;
#define file(x) freopen(x".in","r",stdin),freopen(x".out","w",stdout)
inline void read(int &ans){
  ans=0;char x=getchar();bool f=0;
  while(x<‘0‘||x>‘9‘){if(x==‘-‘)f=1;x=getchar();}
  while(x>=‘0‘&&x<=‘9‘)ans=ans*10+x-‘0‘,x=getchar();
  if(f)ans=-ans;
}
typedef int db;//此题不用开double
const int MAXN=5000+10;
struct Po{//定义点(向量)
  db x,y;
  Po(){};
  Po(int x,int y):x(x),y(y){}
  Po operator-(const Po A)const{return Po(x-A.x,y-A.y);}
  db operator*(const Po A)const{return x*A.y-y*A.x;}
};
int n,m,ans[MAXN],first=true;
db X1,Y1,X2,Y2,U[MAXN],L[MAXN];

bool check(Po C,int ID){
  Po A=Po(L[ID],Y2);
  Po B=Po(U[ID],Y1);
  return (C-A)*(B-A)>0;
}

int find(db x,db y){
  int l=0,r=n+1;
  while(l<r){
    int mid=(l+r)>>1;
    if(check(Po(x,y),mid))l=mid+1;
    else r=mid;
  }
  return l-1;
}

db x,y;
int main(){
  while(scanf("%d",&n)&&n){
    if(first)first=false;else if(n)puts("");
    memset(ans,0,sizeof(ans));
    read(m),read(X1),read(Y1),read(X2),read(Y2);
    U[n]=L[0]=X1,U[n+1]=L[n+1]=X2;
    for(int i=1;i<=n;i++)read(U[i]),read(L[i]);
    for(int i=0;i<m;i++){
      read(x),read(y);
      ans[find(x,y)]++;
    }
    for(int i=0;i<=n;i++)printf("%d: %d\n",i,ans[i]);
  }
  return 0;
}
时间: 2024-10-25 12:52:17

TOYS(计算几何-入门)的相关文章

【POJ】2318 TOYS ——计算几何+二分

TOYS Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 10281   Accepted: 4924 Description Calculate the number of toys that land in each bin of a partitioned toy box. Mom and dad have a problem - their child John never puts his toys away w

hdu 1086(计算几何入门题——计算线段交点个数)

链接:http://acm.hdu.edu.cn/showproblem.php?pid=1086 You can Solve a Geometry Problem too Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 7167    Accepted Submission(s): 3480 Problem Description Ma

计算几何入门向

这是一个计算几何入门的教程. 与计算几何密切相关的就是坐标系,坐标系上的点可以用下面数据结构实现. struct Point { double x,y; Point(int x,int y) :x(x),y(y){}; };typedef Point Vector; 向量也是经常需要的,由于和点所需储存的信息相同,可以直接定义为别名. 由于需要使用大量加减乘除,我们可以重载运算符达到很好的使用效果. /× 挖坑,有时间再写代码 ×/ 我们也可以用STL的虚数类来实现点和向量. typedef c

[您有新的未分配科技点]计算几何入门(1):点,向量以及向量的简单应用

在打了一阵数据结构之后,老师表示"今天晚上让学长给你们讲一下计算几何"--然后就死了.jpg 昨天晚上一直在推数学的式子以及回顾讲课的笔记--计算几何特点就是多而杂,即使是入门部分也是如此-- 首先,我们从二维的几何问题开始处理. 我们知道,高中解析几何计算几何的基础是向量(Vector)和点(Point),所以我们先来表示这两个概念: 在计算几何中,点和向量一般用结构体来存储,像这样: 1 struct Point 2 { 3 double x,y,rad; 4 Point(doub

poj 2318 TOYS(计算几何 点与线段的关系)

TOYS Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 12015   Accepted: 5792 Description Calculate the number of toys that land in each bin of a partitioned toy box. Mom and dad have a problem - their child John never puts his toys away w

计算几何入门模板(持续更新)

我也算是刚入门计算几何吧,想写一篇入门的模板,让那些和我一样刚入门的人都能看懂就好. 首先要有一些理论知识,这可以百度,我就不多说了,通过百度,你要知道: ①叉积可以判断3个点共线,还可以判断2个点构成直线,第3个点在直线的左边还是右边. ②判断两条线段相交要有2个条件,一个是矩形的什么定理(名字太长,忘了)另一个就是4个点的叉积相乘小于0(也就是异号) 之后就可以看下我收集的简单的模板了. #include <map> #include <set> #include <li

计算几何入门之aizu两题 Projection Reflection

---恢复内容开始--- 使用complex类来写计算几何. 第一题 传送门: 题意给定一直线输入一个点求输入点到该直线射影交点的坐标: = p0到p2向量称为v2,p0到p1向量称为v1 易求得p0到t的向量为 (v2·v1)*(v1的方向向量) . 用复数表示每个点和每个向量,则将v1*(v2的共轭复数)得到的实部就是x1*x2虚部就是y1*y2. 这样求得了p0到t的向量v3,所以ansx=xp0+xv3,ansy=yp0+yv3; 第二题  题意类似,做法相同.不再赘述. 现在贴第二题代

POJ 2318 TOYS(计算几何)

跨产品的利用率推断点线段向左或向右,然后你可以2分钟 代码: #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N = 5005; int n, m, x1, y1, x2, y2; struct Point { int x, y; Point() {} Point(int x, int y) { this->x = x; this-&g

POJ-2318 TOYS 计算几何 判断点在线段的位置

题目链接:https://cn.vjudge.net/problem/POJ-2318 题意 在一个矩形内,给出n-1条线段,把矩形分成n快四边形 问某些点在那个四边形内 思路 二分+判断点与位置关系 提交过程 WA*n x1和x2,y1和y2在复制的时候没分清(哭 WA 可能存在二分问题? AC 代码 #define PI 3.1415926 #include <cmath> #include <cstdio> #include <vector> #include &