zoukankan      html  css  js  c++  java
  • 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
    ",i,ans[i]);
    112         cout<<endl;
    113     }
    114     return 0;
    115 }
     
  • 相关阅读:
    洛谷P4979 矿洞:坍塌
    [SHOI2015]脑洞治疗仪
    洛谷P2135 方块消除
    洛谷P1436 棋盘分割
    洛谷P2796 Facer的程序
    浅谈位运算
    [SDOI2006]最短距离
    12耐心_预测未来
    11耐心_有效市场假说
    02C++条件变量
  • 原文地址:https://www.cnblogs.com/shimu/p/5830322.html
Copyright © 2011-2022 走看看