poj 2318 叉积(附带kuangbin关于点的叉积,点积,点绕原点旋转,两直线关系模版)

转自  http://www.cnblogs.com/kuangbin/p/3188484.html

kuangbin关于点的叉积,点积,点绕原点旋转,两直线关系模版:
int sgn(double x){
    if(fabs(x) < eps) return 0;
    if(x < 0) return -1;
    else return 1;

}
struct Point{
    int 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;
    }
    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表示平行,为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);
    }
};

 

 
就是给了m个点,落在n+1个区域中,问各个区域有多少个点。
就是利用叉积去判断点在线段的哪一侧,可以二分去做,比较快。
  1 #include <cstdio>
  2 #include <cstring>
  3 #include <vector>
  4 #include <algorithm>
  5 #include <iostream>
  6 #include <map>
  7 #include <queue>
  8 #include <stack>
  9 #include <cmath>
 10 //#pragma comment(linker, "/STACK:102400000,102400000")
 11 using namespace std;
 12 #define PF(x) cout << "debug: " << x << " ";
 13 #define EL cout << endl;
 14 #define PC(x) puts(x);
 15 typedef long long ll;
 16 #define CLR(x, v) sizeof (x, v, sizeof(x))
 17 using namespace std;
 18 const int INF = 0x5f5f5f5f;
 19 const int  N= 2e5 + 10;
 20 const int mod=1e9 + 7;
 21 const int maxn = 5e3 + 10;
 22 const double eps = 1e-8;
 23 const double PI = acos(-1.0);
 24 int n,m,ans[maxn];
 25 int sgn(double x){
 26     if(fabs(x) < eps) return 0;
 27     if(x < 0) return -1;
 28     else return 1;
 29 
 30 }
 31 struct Point{
 32     int x,y;
 33     Point() { }
 34     Point(double _x,double _y){
 35         x = _x,y = _y;
 36     }
 37     Point operator - (const Point &b) const{ //相对坐标
 38         return Point(x - b.x,y - b.y);
 39     }
 40     double operator ^(const Point &b)const{//叉积
 41         return x*b.y - y*b.x;
 42     }
 43     double operator *(const Point &b)const{//点积
 44         return x*b.x + y*b.y;
 45     }
 46     void transXY(double B){
 47         double tx = x,ty = y;
 48         x = tx*cos(B) - ty*sin(B);
 49         y = tx*sin(B) + ty*cos(B);
 50     }
 51 };
 52 struct Line{
 53     Point s,e;
 54     Line() { }
 55     Line (Point _s,Point _e){
 56         s = _s,e = _e;
 57     }
 58     //两直线相交求交点
 59     //第一个值为0表示直线重合,为1表示平行,为2是相交
 60     //只有第一个值为2时交点才有意义
 61     pair<int,Point> operator &(const Line &b) const{
 62         Point res = s;
 63         if(sgn((s-e)^(b.s-b.e)) == 0){
 64             if(sgn((s-b.e)^(b.s-b.e)) == 0)
 65                 return make_pair(0,res);//重合
 66             else
 67                 return make_pair(1,res);
 68         }
 69         double t = ((s-b.s)^(b.s-b.e))/((s-e)^(b.s-b.e));
 70         res.x += (e.x-s.x)*t;
 71         res.y += (e.y-s.y)*t;
 72         return make_pair(2,res);
 73     }
 74 };
 75 int pmul(Point a,Point b,Point c){
 76     return (b-a) ^ (c-a);
 77 }
 78 int main()
 79 {
 80   // freopen("in.txt","r",stdin);
 81     while(~scanf("%d",&n)){
 82         if(n == 0)
 83             break;
 84         memset(ans,0,sizeof(ans));
 85         double x1,y1,x2,y2;
 86         scanf("%d%lf%lf%lf%lf",&m,&x1,&y1,&x2,&y2);
 87         Line line[maxn];
 88         int ui,li;
 89         for(int i = 0;i < n;i++){
 90             scanf("%d%d",&ui,&li);
 91             line[i] = Line(Point(ui,y1),Point(li,y2));
 92         }
 93         line[n] = Line(Point(x2,y1),Point(x2,y2));
 94         while(m--){
 95             int x,y;
 96             scanf("%d%d",&x,&y);
 97             Point p = Point(x,y);
 98             int tmp;
 99             int l = 0,r = n;
100             while(l <= r){
101                 int mid = (l+r)>>1;
102                 if(pmul(p,line[mid].s,line[mid].e) < 0){
103                     tmp = mid;
104                     r = mid - 1;
105                 }
106                 else l = mid + 1;
107             }
108             ans[tmp]++;
109         }
110         for(int i = 0;i <= n;i++)
111             printf("%d: %d\n",i,ans[i]);
112         cout<<endl;
113     }
114     return 0;
115 }

 

 
posted @ 2016-09-01 16:16  十目  阅读(285)  评论(0编辑  收藏  举报