POJ 2318 TOYS

来源:互联网 发布:unix内核源码剖析 编辑:程序博客网 时间:2024/04/27 20:09

突然发现线代好多都忘了

新学了一个知识点,由向量的叉积来判断某点在向量的左侧还是右侧

设矢量P = ( x1, y1 ),Q = ( x2, y2 ),则矢量叉积定义为由(0,0)、p1、p2和p1+p2所组成的平行四边形的带符号的面积,即:P×Q = x1*y2 - x2*y1,其结果是一个伪矢量。 
    显然有性质 P × Q = - ( Q × P ) 和 P × ( - Q ) = - ( P × Q )。 
叉积的一个非常重要性质是可以通过它的符号判断两矢量相互之间的顺逆时针关系: 
若 P × Q > 0 , 则P在Q的顺时针方向。 
若 P × Q < 0 , 则P在Q的逆时针方向。 
若 P × Q = 0 , 则P与Q共线,但可能同向也可能反向。 
叉积的方向与进行叉积的两个向量都垂直,所以叉积向量即为

#include<stdio.h>#include<string>#include<math.h>#include<iostream>using namespace std;const int N=105;int n,m;double max(double a,double b) {return a>b?a:b;}double min(double a,double b) {return a<b?a:b;}const double eps = 1e-8;const double PI = acos(-1.0);int sgn(double x){if(fabs(x) < eps)return 0;if(x < 0)return -1;else return 1;}struct Point{double x,y;Point(){}Point(double _x,double _y){x = _x;y = _y;}Point operator -(const Point &b)const{return Point(x - b.x,y - b.y);}//叉积double operator ^(const Point &b)const{return x*b.y - y*b.x;}//点积double operator *(const Point &b)const{return x*b.x + y*b.y;}//绕原点旋转角度B(弧度值),后x,y的变化void transXY(double B){double tx = x,ty = y;x = tx*cos(B) - ty*sin(B);y = tx*sin(B) + ty*cos(B);}};struct Line{Point s,e;Line(){}Line(Point _s,Point _e){s = _s;e = _e;}//两直线相交求交点//第一个值为0表示直线重合,为1表示平行,为0表示相交,为2是相交//只有第一个值为2时,交点才有意义pair<int,Point> operator &(const Line &b)const{Point res = s;if(sgn((s-e)^(b.s-b.e)) == 0){if(sgn((s-b.e)^(b.s-b.e)) == 0)return make_pair(0,res);//重合else return make_pair(1,res);//平行}double t = ((s-b.s)^(b.s-b.e))/((s-e)^(b.s-b.e));res.x += (e.x-s.x)*t;res.y += (e.y-s.y)*t;return make_pair(2,res);}};bool inter(Line l1,Line l2){returnmax(l1.s.x,l1.e.x) >= min(l2.s.x,l2.e.x) &&max(l2.s.x,l2.e.x) >= min(l1.s.x,l1.e.x) &&max(l1.s.y,l1.e.y) >= min(l2.s.y,l2.e.y) &&max(l2.s.y,l2.e.y) >= min(l1.s.y,l1.e.y) &&sgn((l2.s-l1.e)^(l1.s-l1.e))*sgn((l2.e-l1.e)^(l1.s-l1.e)) <= 0 &&sgn((l1.s-l2.e)^(l2.s-l2.e))*sgn((l1.e-l2.e)^(l2.s-l2.e)) <= 0;}Line seg[5005];Point b[5005];//m个玩具int ans[5005];int Multi(Point p1,Point p2,Point p0) {//判断点在向量的哪一侧return (p1.x - p0.x) * (p2.y - p0.y) - (p2.x - p0.x) * (p1.y - p0.y);  }void judge(Point p) {int l,r,mid;l=0;r=n-1;while(l<r) {mid=(l+r)>>1;if (Multi(p,seg[mid].s,seg[mid].e)>0) l=mid+1;else r=mid;}if (Multi(p,seg[l].s,seg[l].e)<0) ans[l]++;//<0为左侧,其余为右侧else ans[l+1]++;}int main() {#ifndef ONLINE_JUDGEfreopen("in.txt","r",stdin);#endifwhile(scanf("%d%d",&n,&m),n) {memset(ans,0,sizeof(ans));int i,j;Point s,g,u,l;Point p;scanf("%lf%lf%lf%lf",&s.x,&s.y,&g.x,&g.y);//seg[0].e=s;seg[0].s.x=s.x;seg[0].s.y=g.y;u.y=s.y;l.y=g.y;for(i=0;i<n;i++) {scanf("%lf%lf",&u.x,&l.x);seg[i].e=l;seg[i].s=u;//由底部指向上}//seg[n+1].s=g;seg[n+1].e.x=g.x;seg[n+1].e.y=s.y;for(j=0;j<m;j++) {scanf("%lf%lf",&p.x,&p.y);judge(p);}for(i=0;i<=n;i++) printf("%d: %d\n",i,ans[i]);printf("\n");}return 0;}


0 0