计算几何 (⊙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\n",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\n");
        for (int i=1;i<=m;i++) 
        if (cnt[i]!=0)  
         printf("%d: %d\n",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\n",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\n",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

未完待续

posted @ 2018-05-16 21:06  泪寒之雪  阅读(164)  评论(0编辑  收藏  举报