zoukankan      html  css  js  c++  java
  • 计算几何 (⊙o⊙)…

    POJ 2318 TOYS(推荐) 
    http://acm.pku.edu.cn/JudgeOnline/problem?id=2318 

    #include<iostream>
    #include<cstring>
    #define y1 xy
    using namespace std;
    struct Point{
        int x,y;
        Point() {}
        Point(int _x,int _y){
            x=_x; y=_y;
        }
        Point operator +(const Point X)const{
          return Point(x+X.x,y+X.y);
        }
        Point operator -(const Point X)const{
          return Point(x-X.x,y-X.y);
        }
    }P;
    int Dit(Point X,Point Y){
        return X.x*Y.x+X.y*Y.y;
    }
    int Det(Point X,Point Y){
        return X.x*Y.y-X.y*Y.x;
    }
    struct Line{
        Point S,T;
        Line() {}
        Line(Point _s,Point _t){
            S=_s; T=_t;
        }
    }L[5007];
    int ans[5007];
    int Li_P(Point A,Line B){
        return Det(B.S-A,B.T-A);
    }
    int n,m,x1,y1,x2,y2,x,y;
    int main () {
    //    freopen("a.in","r",stdin);
        while (scanf("%d%d%d%d%d%d",&n,&m,&x1,&y1,&x2,&y2)!=EOF&&n) {
            for (int i=1;i<=n;i++) {
                scanf("%d%d",&x,&y);
                L[i]=Line(Point(x,y1),Point(y,y2));
            }
            L[n+1]=Line(Point(x2,y1),Point(x2,y2));
            for (int i=1;i<=m;i++) {
                scanf("%d%d",&P.x,&P.y);
                for (int i=1;i<=n+1;i++) 
                 if (Li_P(P,L[i])<0) 
                  { ans[i-1]++; break;}
            }
            for (int i=0;i<=n;i++) 
             printf("%d: %d
    ",i,ans[i]);
            memset(ans,0,sizeof ans);
           puts("");
        }
        return 0;
    }
    View Code


    POJ 2398 Toy Storage(推荐) 
    http://acm.pku.edu.cn/JudgeOnline/problem?id=2398 
    一个矩形,有被若干直线分成N个格子,给出一个点的坐标,问你该点位于哪个点中。 
    知识点:其实就是点在凸四边形内的判断,若利用叉积的性质,可以二分求解。

    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #define y1 xy
    using namespace std;
    struct Point{
        int x,y;
        Point() {}
        Point(int _x,int _y){
            x=_x; y=_y;
        }
        Point operator +(const Point X)const{
          return Point(x+X.x,y+X.y);
        }
        Point operator -(const Point X)const{
          return Point(x-X.x,y-X.y);
        }
    }P;
    int Dit(Point X,Point Y){
        return X.x*Y.x+X.y*Y.y;
    }
    int Det(Point X,Point Y){
        return X.x*Y.y-X.y*Y.x;
    }
    struct Line{
        Point S,T;
        Line() {}
        Line(Point _s,Point _t){
            S=_s; T=_t;
        }
        bool operator <(const Line PP)const{
            return (min(S.x,T.x)==min(PP.S.x,PP.T.x))?
            (min(S.y,T.y)<min(PP.S.y,PP.T.y)):min(S.x,T.x)<min(PP.S.x,PP.T.x);
        }
    }L[5007];
    int ans[5007],cnt[5007];
    int Li_P(Point A,Line B){
        return Det(B.S-A,B.T-A);
    }
    int n,m,x1,y1,x2,y2,x,y;
    int main () {
        while (scanf("%d%d%d%d%d%d",&n,&m,&x1,&y1,&x2,&y2)!=EOF&&n) {
            for (int i=1;i<=n;i++) {
                scanf("%d%d",&x,&y);
                L[i]=Line(Point(x,y1),Point(y,y2));
            }
            L[n+1]=Line(Point(x2,y1),Point(x2,y2));
            sort(L+1,L+n+2);
            for (int i=1;i<=m;i++) {
                scanf("%d%d",&P.x,&P.y);
                for (int i=1;i<=n+1;i++) 
                 if (Li_P(P,L[i])<0) 
                  { ans[i-1]++; break;}
            }
            for (int i=0;i<=n;i++) cnt[ans[i]]++;
            printf("Box
    ");
            for (int i=1;i<=m;i++) 
            if (cnt[i]!=0)  
             printf("%d: %d
    ",i,cnt[i]);
            memset(ans,0,sizeof ans);
            memset(cnt,0,sizeof ans);
        }
        return 0;
    }
    View Code

    POJ 3304 Segments 
    http://acm.pku.edu.cn/JudgeOnline/problem?id=3304 
    知识点:线段与直线相交,注意枚举时重合点的处理

    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define db double
    #define N 4007
    const db pi=acos((db)-1); 
    #define exp 1e-8
    int dcmp(db x,db y) {
        if (abs(x-y)<exp) return 0;
        return x<y?-1:1;
    }
    using namespace std;
    struct Point{
        db x,y;
        Point() {}
        Point(db _x,db _y):x(_x),y(_y){}
        void Int() {scanf("%lf%lf",&x,&y);}
        Point operator +(const Point X)const{
            return Point(x+X.x,y+X.y);
        } 
        Point operator -(const Point X)const{
            return Point(x-X.x,y-X.y);
        }
        Point operator *(const db X)const{
            return Point(x*X,y*X);
        }
        Point operator -(const db X)const{
            return Point(x/X,y/X);
        }
        bool operator <(const Point X)const{
            return dcmp(x,X.x)==0?y<X.y:x<X.x;
        }
        bool operator ==(const Point X)const{
            return dcmp(x,X.x)==0&&dcmp(y,X.y)==0;
        }
    };
    db Dit(Point X,Point Y){return X.x*Y.x+X.y*Y.y;}
    db Det(Point X,Point Y){return X.x*Y.y-X.y*Y.x;}
    struct Line{
        Point S,T;
        void up() {
           if (T<S) swap(S,T);
        }
        void Int() {
            S.Int(); T.Int(); up();
        }
        Line() {}
        Line(Point _s,Point _t){
            S=_s; T=_t; up();
        }
    }L[N];
    db Li_P(Line X,Point T){  //线段和点的方向 
        return Det(X.S-T,X.T-T);
    }
    bool Li_Li(Line X,Line Y){  //直线和线段不严格交 
        if (Li_P(X,Y.S)*Li_P(X,Y.T)>exp) return 0;
        return 1;
    }
    int T,n,ans;
    bool check(Line P){
        if (P.S==P.T) return 0;
        for (int i=1;i<=n;i++)
         if (!Li_Li(P,L[i])) return 0;
        return 1;
    }
    signed main () {
        freopen("c.in","r",stdin);
        scanf("%d",&T);
        while (T--) {
            scanf("%d",&n);
            for (int i=1;i<=n;i++) L[i].Int();
            if (n==1) {puts("Yes!"); continue;}
            ans=0;
            for (int i=1;i<=n&&!ans;i++)
             for (int j=i+1;j<=n&&!ans;j++){
                  ans|=check(Line(L[i].S,L[j].S));
                  ans|=check(Line(L[i].S,L[j].T));
                  ans|=check(Line(L[i].T,L[j].S));
                  ans|=check(Line(L[i].T,L[j].T));
    //              if (ans) cerr<<i<<j<<endl;
              }
            puts(ans?"Yes!":"No!");
        } return 0;
    }
    View Code

    POJ 1269 Intersecting Lines 
    http://acm.pku.edu.cn/JudgeOnline/problem?id=1269 
    知识点:直线相交判断,求相交交点

    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define db double
    #define N 4007
    const db pi=acos((db)-1); 
    #define exp 1e-8
    int dcmp(db x) {
        if (abs(x)<exp) return 0;
        return x<0?-1:1;
    }
    int dcmp(db x,db y) {
        if (abs(x-y)<exp) return 0;
        return x<y?-1:1;
    }
    using namespace std;
    struct Point{
        db x,y;
        Point() {}
        Point(db _x,db _y):x(_x),y(_y){}
        void Int() {scanf("%lf%lf",&x,&y);}
        Point operator +(const Point X)const{
            return Point(x+X.x,y+X.y);
        } 
        Point operator -(const Point X)const{
            return Point(x-X.x,y-X.y);
        }
        Point operator *(const db X)const{
            return Point(x*X,y*X);
        }
        Point operator -(const db X)const{
            return Point(x/X,y/X);
        }
        bool operator <(const Point X)const{
            return dcmp(x,X.x)==0?y<X.y:x<X.x;
        }
        bool operator ==(const Point X)const{
            return dcmp(x,X.x)==0&&dcmp(y,X.y)==0;
        }
    };
    db Dit(Point X,Point Y){return X.x*Y.x+X.y*Y.y;}
    db Det(Point X,Point Y){return X.x*Y.y-X.y*Y.x;}
    struct Line{
        Point S,T;
        void up() {
           if (T<S) swap(S,T);
        }
        void Int() {
            S.Int(); T.Int(); up();
        }
        Line() {}
        Line(Point _s,Point _t){
            S=_s; T=_t; up();
        }
        bool operator ==(const Line X)const{
            return S==X.S&&T==X.T;
        }
    }X,Y;
    bool Pin(const Line Y,const Line X){
        return dcmp(Det(Y.T-Y.S,X.T-X.S))==0;
    }
    db Li_P(Line X,Point T){  //线段和点的方向 
        return Det(X.S-T,X.T-T);
    }
    bool Li_Li(Line X,Line Y){  //直线和线段不严格交 
        if (Li_P(X,Y.S)*Li_P(X,Y.T)>exp) return 0;
        return 1;
    }
    bool ty(Line X,Line Y){ //尝试求交,判特殊情况 
        if (!Pin(X,Y)) return 0;
        if (dcmp(Li_P(X,Y.S))==0) 
          { puts("LINE"); return 1;}
        puts("NONE"); return 1; 
    }
    Point Jiao(Line X,Line Y){  //直线求交 
        Point res=X.S;
        db t=Det(X.S-Y.S,Y.S-Y.T)/Det(X.S-X.T,Y.S-Y.T);
        res.x+=(X.T.x-X.S.x)*t;
        res.y+=(X.T.y-X.S.y)*t;
        printf("POINT %.2lf %.2lf
    ",res.x,res.y);
        return res;
    }
    int T,n,ans;
    signed main () {
    //    freopen("d.in","r",stdin);
        scanf("%d",&T);
        puts("INTERSECTING LINES OUTPUT");
        while (T--) {
            X.Int(); Y.Int();
            if (ty(X,Y)) continue;
            Jiao(X,Y);
        } 
        puts("END OF OUTPUT");
    
        return 0;
    }
    View Code

    POJ 1410 Intersection 
    http://acm.pku.edu.cn/JudgeOnline/problem?id=1410 
    知识点:线段与矩形相交。正确理解题意中相交的定义。 

    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define db double
    #define N 4007
    const db pi=acos((db)-1); 
    #define exp 1e-8
    int dcmp(db x) {
        if (abs(x)<exp) return 0;
        return x<0?-1:1;
    }
    int dcmp(db x,db y) {
        if (abs(x-y)<exp) return 0;
        return x<y?-1:1;
    }
    using namespace std;
    struct Point{
        db x,y;
        Point() {}
        Point(db _x,db _y):x(_x),y(_y){}
        void Int() {scanf("%lf%lf",&x,&y);}
        Point operator +(const Point X)const{
            return Point(x+X.x,y+X.y);
        } 
        Point operator -(const Point X)const{
            return Point(x-X.x,y-X.y);
        }
        Point operator *(const db X)const{
            return Point(x*X,y*X);
        }
        Point operator -(const db X)const{
            return Point(x/X,y/X);
        }
        bool operator <(const Point X)const{
            return dcmp(x,X.x)==0?y<X.y:x<X.x;
        }
        bool operator ==(const Point X)const{
            return dcmp(x,X.x)==0&&dcmp(y,X.y)==0;
        }
    };
    #define sqr(x) ((x)*(x))
    db Dit(Point X,Point Y){return X.x*Y.x+X.y*Y.y;}
    db Det(Point X,Point Y){return X.x*Y.y-X.y*Y.x;}
    db Dis(Point X,Point Y){return sqrt(sqr(X.x-Y.x)+sqr(X.y-Y.y));}
    struct Line{
        Point S,T,ET;
        void up() {
           if (T<S) swap(S,T);
           ET=T-S;
        }
        void Int() {
            S.Int(); T.Int(); up();
        }
        Line() {}
        Line(Point _s,Point _t){
            S=_s; T=_t; up();
        }
        bool operator ==(const Line X)const{
            return S==X.S&&T==X.T;
        }
    }X,Y;
    bool Pin(const Line Y,const Line X){
        return dcmp(Det(Y.T-Y.S,X.T-X.S))==0;
    }
    db Li_P(Line X,Point T){  //线段和点的方向 
        return Det(X.S-T,X.T-T);
    }
    bool Li_Li(Line X,Line Y){  //直线和线段不严格交 
        if (Li_P(X,Y.S)*Li_P(X,Y.T)>exp) return 0;
        return 1;
    }
    bool Seg_Seg(Line X,Line Y){ //线段与线段不严格交 
        return Li_Li(X,Y)&&Li_Li(Y,X); 
    }
    bool ty(Line X,Line Y){ //尝试求交,判特殊情况 
        if (!Pin(X,Y)) return 0;
        if (dcmp(Li_P(X,Y.S))==0) 
          { /*puts("LINE");*/ return 1;}
        /*puts("NONE");*/ return 1; 
    }
    Point Jiao(Line X,Line Y){  //直线求交 
        Point res=X.S;
        db t=Det(X.S-Y.S,Y.S-Y.T)/Det(X.S-X.T,Y.S-Y.T);
        res.x+=(X.T.x-X.S.x)*t;
        res.y+=(X.T.y-X.S.y)*t;
    //    printf("POINT %.2lf %.2lf
    ",res.x,res.y);
        return res;
    }
    int T,n,ans;
    bool che(Point X,Line S){
        return dcmp(S.S.x,X.x)<=0&&dcmp(X.x,S.T.x)<=0&&
        dcmp(min(S.S.y,S.T.y),X.y)<=0&&dcmp(max(S.S.y,S.T.y),X.y)>=0;
    }
    //#define dblcmp dcmp
    //#define Max max
    //#define Min min 
    //double Multi(Point p1, Point p2, Point p0) {  
    //    return (p1.x-p0.x)*(p2.y-p0.y)-(p1.y-p0.y)*(p2.x-p0.x);  
    //}  
    //bool SS(Line XX,Line YY) {  
    //    Point a=XX.S,b=XX.T,c=YY.S,d=YY.T;
    //    if (dblcmp(Max(a.x, b.x)-Min(c.x, d.x)) >= 0 && dblcmp(Max(c.x, d.x)-Min(a.x, b.x)) >= 0  
    //        && dblcmp(Max(a.y, b.y)-Min(c.y, d.y)) >= 0 && dblcmp(Max(c.y, d.y)-Min(a.y, b.y)) >= 0  
    //        && dblcmp(Multi(a, d, c)*Multi(b, d, c)) <= 0 && dblcmp(Multi(c, b, a)*Multi(d, b, a)) <= 0)  
    //                return true;  
    //    return false;  
    //}  
    //#define Seg_Seg SS
    int main () {
        freopen("e.in","r",stdin);
        scanf("%d",&T);
        while (T--) {
            X.Int(); Y.Int();
            ans=0;
            ans|=Seg_Seg(X,Line(Y.S,Point(Y.S.x,Y.T.y)));
            ans|=Seg_Seg(X,Line(Y.S,Point(Y.T.x,Y.S.y)));
            ans|=Seg_Seg(X,Line(Point(Y.S.x,Y.T.y),Y.T));
            ans|=Seg_Seg(X,Line(Point(Y.T.x,Y.S.y),Y.T));
            ans|=che(X.S,Y);  ans|=che(X.T,Y);
            puts(ans?"T":"F");
        } 
        return 0;
    }
    View Code

    未完待续

  • 相关阅读:
    HTML5(一)初识HTML5
    iOS手机流量抓包rvictl
    mysql 安全模式
    DNS解析
    Git删除文件
    Git创建本地仓库并推送至远程仓库
    【python】字典/dictionary操作
    Gson解析复杂JSON字符串的两种方式
    apk安装提示:Failure [INSTALL_FAILED_DUPLICATE_PERMISSION perm=XXX]
    su、sudo、su
  • 原文地址:https://www.cnblogs.com/rrsb/p/9048166.html
Copyright © 2011-2022 走看看