计算几何题目推荐第一期AC代码

来源:互联网 发布:nba2015常规赛mvp数据 编辑:程序博客网 时间:2024/06/15 02:12

很多题,很多代码:一、点,线,面,形基本关系,点积叉积的理解/*poj2318toys*///判断箱子每一个块内有多少个玩具,可以用叉积的性质找到玩具的位置,过程采用二分查找。#include <cstdio>#include <cstring>using namespace std;#define EPS 1e-8const int MAXN = 5010;struct Point{    double x,y;    Point(){}    Point(double _x,double _y):x(_x),y(_y){}    void input(){        scanf("%lf%lf",&x,&y);    }};inline double difcross(Point p1,Point p0,Point p2){    return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);}struct pi{    Point first;    Point second;}PII[MAXN];int mark[MAXN];int n,m;double x1,y1,x2,y2;int main(){    int k = 0;    while(scanf("%d",&n) != EOF){        if(n == 0)break;        k ++;        if(k != 1)putchar('\n');        scanf("%d%lf%lf%lf%lf",&m,&x1,&y1,&x2,&y2);        memset(mark,0,sizeof(mark));        double ui,li;        for(int i = 1; i <= n; ++i){            scanf("%lf%lf",&ui,&li);            PII[i].first = Point(ui,y1);            PII[i].second = Point(li,y2);        }        Point toy;        for(int i = 0; i < m; ++i){            toy.input();            int low = 1,high = n,mid;            while(low <= high){                mid = (low + high)/2;                if(difcross(toy,PII[mid].second,PII[mid].first) > 0)                    low = mid + 1;                else high = mid - 1;            }            //printf("low = %d  high = %d mid = %d\n",low,high,mid);            mark[high] ++;        }        for(int i = 0; i <= n; ++i)            printf("%d: %d\n",i,mark[i]);    }}//另外,poj2398Toy Storage与此题雷同,不再重复/*POJ3304 Segments*///  判断线段与直线相交#include<iostream>#include<cmath>using namespace std;#define ESP 1e-8inline int dblcmp(double d){    if(fabs(d) < ESP)return 0;    else return d > 0 ? 1 : -1;}struct Point{    double x,y;};struct Seg{    Point a,b;};struct xlg{    double x,y;};inline double pdis(Point a,Point b){    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}inline double difpro(Point a,Point b,Point c){    double x1 = b.x - a.x,           y1 = b.y - a.y,           x2 = c.x - a.x,           y2 = c.y - a.y;    return (x1*y2 - x2*y1);}inline int seg_line_intersect(Seg seg, Point l1,Point l2){    if(dblcmp(difpro(l1,seg.a,l2)*difpro(l1,seg.b,l2)) <= 0)return 1;    return 0;}const int maxn = 110;Seg seg[maxn];int n;inline bool cal(Point l1,Point l2){    for(int i = 0; i < n; i++){        if(!seg_line_intersect(seg[i],l1,l2))        return 0;    }    return 1;}int main(){    int cas,i,j;    double x,y;    scanf("%d",&cas);    while(cas--){        int flag = 0;        scanf("%d",&n);        for(i = 0; i < n; i++)            scanf("%lf%lf%lf%lf",&seg[i].a.x,&seg[i].a.y,&seg[i].b.x,&seg[i].b.y);        for(i = 0; i < n; i++){            for(j = i; j < n; j++){                if(dblcmp(pdis(seg[i].a,seg[j].a)) > 0){                    if(cal(seg[i].a,seg[j].a)){                        flag = 1;break;                    }                }                if(dblcmp(pdis(seg[i].a,seg[j].b)) > 0){                    if(cal(seg[i].a,seg[j].b)){                        flag = 1;break;                    }                }                if(dblcmp(pdis(seg[i].b,seg[j].a)) > 0){                    if(cal(seg[i].b,seg[j].a)){                        flag = 1;break;                    }                }              if(dblcmp(pdis(seg[i].b,seg[j].b)) > 0){                    if(cal(seg[i].b,seg[j].b)){                        flag = 1;break;                    }                }            }        }        if(flag)printf("Yes!\n");        else printf("No!\n");    }    return 0;}/*poj1269Intersecting Lines*///直线相交判断,注意是一条直线(共线)的情况#include <cstdio>#include <cstring>#include <cmath>using namespace std;#define feq(a,b) (fabs((a)-(b))<EPS)#define EPS 1e-8struct Point{    double x,y;    Point(){}    Point(double _x,double _y):x(_x),y(_y){}    void input(){        scanf("%lf%lf",&x,&y);    }};struct Line{    double a,b,c;};inline void getline(Point p1,Point p2,Line &l){        l.a = p2.y - p1.y;        l.b = p1.x - p2.x;        l.c = p1.y*p2.x - p1.x*p2.y;        if (l.a < 0) l.a *= -1,l.b *= -1,l.c *= -1;}inline int line_intersect(Line l1,Line l2,Point &ans){    double d=l1.a*l2.b-l2.a*l1.b;    if (feq(d, 0)) return 0;    ans.x = (l2.c*l1.b-l1.c*l2.b)/d;    ans.y = (l2.a*l1.c-l1.a*l2.c)/d;    return 1;}int N;int main(){    scanf("%d",&N);    Point p3,p4,q1,q2,ans;    Line l1,l2;    puts("INTERSECTING LINES OUTPUT");    while(N --){        p3.input();        p4.input();        getline(p3,p4,l1);        q1.input();        q2.input();        getline(q1,q2,l2);        int tmp = line_intersect(l1,l2,ans);        if(tmp == 0){            if(feq(l1.a*l2.b,l2.a*l1.b) && feq(l1.a*l2.c,l2.a*l1.c) && feq(l1.b*l2.c,l2.b*l1.c)){                printf("LINE\n");            }            else printf("NONE\n");        }        else printf("POINT %.2lf %.2lf\n",ans.x,ans.y);    }    puts("END OF OUTPUT");    return 0;}/*poj1556The Doors*/// 利用的计算几何并不多(判断线段相交),建图比较繁琐,然后用dijkstra求最短路即可#include <cstdio>#include <cstring>#include<cmath>using namespace std;#define inf 99999999const int maxn = 200;struct Point {    double x,y;    Point(){}    Point(double _x,double _y):x(_x),y(_y){}};double cross(Point a,Point a1,Point a2){    return (a1.x - a.x)*(a2.y - a.y)-(a2.x - a.x)*(a1.y - a.y);}double dist[maxn][maxn];double pdis(Point a,Point b){    return sqrt( (a.x - b.x)*(a.x - b.x)+(a.y - b.y)*(a.y - b.y) );}int isintersect(Point a1,Point a2,Point b1,Point b2){    if(cross(a1,a2,b1)*cross(a1,a2,b2) < 0 && cross(b1,b2,a1)*cross(b1,b2,a2) < 0)return 1;    return 0;}Point points[maxn];int main(){    int n,i,j;    while(scanf("%d",&n) != EOF){        if(n == -1)break;        int cnt = 1;        double num,x[maxn];        points[0] = Point(0,5);        for(i = 1; i <= n; i ++){            scanf("%lf",&x[i]);            for(j = 0; j < 4; j++){                scanf("%lf",&num);                points[cnt++] = Point(x[i],num);            }        }        points[cnt] = Point(10,5);        int ti,fi,tj,fj;        for(i = 0; i < maxn; i++){            for(j = 0; j < maxn ; j++){                dist[i][j] = inf;            }        }        for(i = 0; i < maxn; i++)dist[i][i] = 0;        for(i = 0; i <= cnt; i++){            for(j = i+1; j <= cnt; j++){                if(points[i].x == points[j].x){                    continue;                }                if(i%4 == 0)ti = i/4;                else ti = i/4+1;                if(j%4 == 0)tj = j/4;                else tj = j/4+1;                int flag = 1;                for(int k= ti + 1; k < tj; k++){                    Point pk1 = Point(x[k],0);                    Point pk2 = Point(x[k],10);                    if(isintersect(points[i],points[j],pk1,points[4*(k-1)+1])){                        flag = 0;break;                    }                    if(isintersect(points[i],points[j],points[4*(k-1)+2],points[4*(k-1)+3])){                        flag = 0;break;                    }                    if(isintersect(points[i],points[j],points[4*(k-1)+4],pk2)){                        flag = 0;                        break;                    }                }                if(flag){                    double tm = pdis(points[i],points[j]);                    dist[i][j] = tm;                    dist[j][i] = tm;                }            }        }        cnt++;        int mark[maxn];        double  dis[maxn];        for(i = 0; i < cnt; i++){            dis[i] = dist[0][i];        }        memset(mark,0,sizeof(mark));        mark[0] = 1;        for(i = 0; i < cnt - 1; i++){            double  mi = inf;            int u = 0;            for(j = 0; j < cnt; j++){                if(!mark[j] && dis[j] < mi){                    mi = dis[j];                    u = j;                }            }            mark[u] = 1;            for(j = 0; j < cnt; j++){                if(!mark[j] && dis[u] + dist[u][j] < dis[j]){                    dis[j] = dis[u] + dist[u][j];                }            }        }        printf("%.2lf\n",dis[cnt-1]);    }    return 0;}/*poj2653Pick-up sticks*///赤裸裸的线段求交#include <cstdio>#include <cstring>#include <cmath>using namespace std;using namespace std;#define EPS 1e-6#define INF 1000000000const int maxn = 100000;struct Point {double x,y;Point(){};Point(double _x,double _y):x(_x),y(_y){}void in(){scanf("%lf%lf",&x,&y);}};double min(double a,double b){return a > b ? b : a;}double max(double a,double b){return a > b ? a : b;}double pdis(Point a,Point b){return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}double cproduct(Point a,Point a1,Point a2){return (a1.x - a.x)*(a2.y - a.y) -(a2.x - a.x)*(a1.y - a.y);}double dproduct(Point a,Point a1,Point a2){return (a1.x-a.x)*(a1.y-a.y) + (a2.x-a.x)*(a2.y-a.y);}bool isIntersected(Point s1, Point e1, Point s2, Point e2) {        return ( max(s1.x, e1.x) >= min(s2.x, e2.x) )        & ( max(s2.x, e2.x) >= min(s1.x, e1.x) )        &( max(s1.y, e1.y) >= min(s2.y, e2.y) )        & ( max(s2.y, e2.y) >= min(s1.y, e1.y) )    & ( cproduct(s2, e1, s1) * cproduct(e1, e2, s1)>0) //>0规范性相交且不包括重合;      & ( cproduct(s1, e2, s2) * cproduct(e2, e1, s2)>0); //>=0包括规范性和非规范性相交且包括重合;}struct seg{Point a,b;};int main(){int n;        seg segs[maxn];while(scanf("%d",&n)!=EOF){if(n == 0)break;for(int i = 0; i < n; i++){scanf("%lf%lf%lf%lf",&segs[i].a.x,&segs[i].a.y,&segs[i].b.x,&segs[i].b.y);}int mark[maxn];memset(mark,0,sizeof(mark));for(int i = 0; i < n; i++){for(int j = i+1; j < n; j++){if(isIntersected(segs[i].a,segs[i].b,segs[j].a,segs[j].b) != 0){mark[i] = 1;break;}}}printf("Top sticks: ");int ans[maxn];int q = -1;for(int i =  0; i < n; i++){if(mark[i] == 0)ans[++q] = i+1;}for(int i = 0; i < q; i++){printf("%d, ",ans[i]);}printf("%d.\n",ans[q]);}return 0;}/*POJ 1066 Treasure Hunt*///线段相交判断#include<iostream>#include<algorithm>#include<cmath>using namespace std;#define ESP 1e-8int dblcmp(double d){    if(fabs(d) < ESP)return 0;    else return d > 0 ? 1 : -1;}struct Point{    double x,y;};struct Seg{    Point a,b;};struct xlg{    double x,y;};double difpro(xlg a,xlg b){    return (a.x*b.y-a.y*b.x);}xlg getxlg(Point a,Point b){    xlg tmp;    tmp.x = b.x - a.x;    tmp.y = b.y - a.y;    return tmp;}int seg_line_intersect(Point a,Point b, Point l1,Point l2){    xlg v1 = getxlg(l1,a),        v2 = getxlg(l1,l2),        v3 = getxlg(l1,b);    if(dblcmp(difpro(v1,v2)*difpro(v3,v2)) < 0)return 1;    return 0;}const int maxn = 35;Seg segs[maxn];Point dest;int n;int main(){    double  y0[maxn],x0[maxn],y100[maxn],x100[maxn];    while(scanf("%d",&n)!=EOF){    memset(y0,0,sizeof(y0));    memset(x0,0,sizeof(x0));    memset(y100,0,sizeof(y100));    memset(x100,0,sizeof(x100));    int qy0 = 1,qx0 = 1, qx100 = 1,qy100 = 1;    for(int i = 0; i < n; i++){        scanf("%lf%lf%lf%lf",&segs[i].a.x,&segs[i].a.y,&segs[i].b.x,&segs[i].b.y);        if(segs[i].a.x == 0)x0[qx0++] = segs[i].a.y;        if(segs[i].a.x == 100)x100[qx100++] = segs[i].a.y;        if(segs[i].a.y == 0)y0[qy0++] = segs[i].a.x;        if(segs[i].a.y == 100)y100[qy100++] = segs[i].a.x;        if(segs[i].b.x == 0)x0[qx0++] = segs[i].b.y;        if(segs[i].b.x == 100)x100[qx100++] = segs[i].b.y;        if(segs[i].b.y == 0)y0[qy0++] = segs[i].b.x;        if(segs[i].b.y == 100)y100[qy100++] = segs[i].b.x;    }    int cnt,mi = 9999999;    scanf("%lf%lf",&dest.x,&dest.y);    if(n == 0){        printf("Number of doors = 1\n");        continue;    }    sort(x0,x0+qx0);    sort(y0,y0+qy0);    sort(x100,x100+qx100);    sort(y100,y100+qy100);    x0[0] = 0;x0[qx0] = 100;    y0[0] = 0;y0[qy0] = 100;    x100[0] = 0;x100[qx100] = 100;    y100[0] = 0; y100[qy100] = 100;    for(int i = 1; i <= qx0; i++){        cnt = 1;        Point t;        t.y = (x0[i-1]+x0[i])/2;        t.x = 0;        for(int j = 0; j < n; j++){            if(seg_line_intersect(t,dest,segs[j].a,segs[j].b))cnt++;        }        if(mi > cnt)mi = cnt;    }     for(int i = 1; i <= qx100; i++){        cnt = 1;        Point t;        t.y = (x100[i-1]+x100[i])/2;        t.x = 100;        for(int j = 0; j < n; j++){            if(seg_line_intersect(t,dest,segs[j].a,segs[j].b))cnt++;        }        if(mi > cnt)mi = cnt;    }     for(int i = 1; i <= qy0; i++){        cnt = 1;        Point t;        t.x = (y0[i-1]+y0[i])/2;        t.y = 0;        for(int j = 0; j < n; j++){            if(seg_line_intersect(t,dest,segs[j].a,segs[j].b))cnt++;        }        if(mi > cnt)mi = cnt;    }     for(int i = 1; i <= qy100; i++){        cnt = 1;        Point t;        t.x = (y100[i-1]+y100[i])/2;        t.y = 100;        for(int j = 0; j < n; j++){            if(seg_line_intersect(t,dest,segs[j].a,segs[j].b))cnt++;        }        if(mi > cnt)mi = cnt;    }    printf("Number of doors = %d\n",mi);    }    return 0;}/*POJ 1410 Intersection*///判断线段是否与矩形相交,分别判断线段是否与矩形的四条边相交,另外注意一下整个线段在矩形中即可,还有这题描述不清,看discuss吧;#include <cstdio>#include <cstring>#include <cmath>using namespace std;#define EPS 1e-8#define sqr(a) ( (a*a) )#define max(a,b) ((a)>(b) ? (a) : (b))#define min(a,b) ((a)<(b) ? (a) : (b))#define feq(a,b) (fabs((a)-(b))<EPS)//a==b#define fbg(a,b) ((a) > EPS+(b)) //a > b#define fsm(a,b) ((b) > EPS+(a)) //a < b#define fbgeq(a,b) ((a) >= (b)-EPS)  //a >= b#define fsmeq(a,b) ((b) >= (a)-EPS)  //a <= bstruct Point{    double x,y;    Point(){}    Point(double _x,double _y):x(_x),y(_y){}    void input(){        scanf("%lf%lf",&x,&y);    }};struct Segment{    Point a,b;    Segment(){}    Segment(Point _a,Point _b):a(_a),b(_b){}};inline double difcross(Point p0,Point p1,Point p2){    return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);}inline bool SegIntersect(Segment s1,Segment s2){    double mxs1x = max(s1.a.x,s1.b.x), mns1x = min(s1.a.x,s1.b.x);    double mxs2x = max(s2.a.x,s2.b.x), mns2x = min(s2.a.x,s2.b.x);    double mxs1y = max(s1.a.y,s1.b.y), mns1y = min(s1.a.y,s1.b.y);    double mxs2y = max(s2.a.y,s2.b.y), mns2y = min(s2.a.y,s2.b.y);    return fsmeq(difcross(s1.a,s1.b,s2.a)*difcross(s1.a,s1.b,s2.b), 0)&&           fsmeq(difcross(s2.a,s2.b,s1.a)*difcross(s2.a,s2.b,s1.b), 0)&&           fbgeq(mxs1x, mns2x)&&fbgeq(mxs2x, mns1x) &&           fbgeq(mxs1y, mns2y)&&fbgeq(mxs2y, mns1y);}Point s,t,p1,p2,p3,p4;Segment s1,s2;int main(){    int n;    scanf("%d",&n);    while(n --){        s.input();        t.input();        p1.input();        p3.input();        double maxx = max(p1.x,p3.x);        double minx = min(p1.x,p3.x);        double maxy = max(p1.y,p3.y);        double miny = min(p1.y,p3.y);        p1 = Point(minx,maxy);        p3 = Point(maxx,miny);        p2 = Point(p1.x,p3.y);        p4 = Point(p3.x,p1.y);        s1 = Segment(s,t);        maxx = max(s.x,t.x);        minx = min(s.x,t.x);        maxy = max(s.y,t.y);        miny = min(s.y,t.y);         bool flag = 0;       if(minx > p1.x + EPS && maxx +EPS < p3.x && maxy +EPS < p1.y          && miny > p3.y+EPS)flag = 1;        s2 = Segment(p1,p2);        if(SegIntersect(s1,s2))flag = 1;        s2 = Segment(p2,p3);         if(SegIntersect(s1,s2))flag = 1;        s2 = Segment(p3,p4);         if(SegIntersect(s1,s2))flag = 1;        s2 = Segment(p4,p1);         if(SegIntersect(s1,s2))flag = 1;        if(!flag)puts("F");        else puts("T");    }    return 0;}/*POJ 1696 Space Ant*///非常好的题目,知道怎么做的话就是个水题,根据Graham求凸包的思想,每次找到最左下的那个点即可(每次排序的基准点改变)#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>using namespace std;#define EPS 1e-8#define feq(a,b) (fabs((a)-(b))<EPS)#define fbg(a,b) ((a) > EPS+(b))#define dis(a, b) ((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y))#define dist(p1, p2, a) (fabs(difcross(p1, a, p2)/sqrt(dis(p1,p2))))const int MAXN = 55;struct Point{    double x,y;    int id;    Point(){}    Point(double _x,double _y):x(_x),y(_y){}    void input(){        scanf("%d%lf%lf",&id,&x,&y);    }};inline double difcross(Point a,Point b,Point c){    return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);}inline double pdis(Point a,Point b){    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}Point p[MAXN];Point p0;int anstop,n,ans[MAXN];inline int cmp(Point a, Point b){    double k = difcross(p0, a, b);    if(feq(k,0) && fbg(pdis(a, p0) , pdis(b, p0)))return 1;    else if( k > EPS ) return 1;     return 0;}int main(){    int cas;    scanf("%d",&cas);    while(cas --){        scanf("%d",&n);        for(int i = 0; i < n ; ++i){            p[i].input();            if(p[i].y < p[0].y)                swap(p[0],p[i]);        }        anstop = 0;        int cur = 0;        p0 = p[cur];        ans[anstop++] = p[cur++].id;        for(int i = 0; i < n - 1; ++i){            sort(p+cur,p+n,cmp);            p0 = p[cur];            ans[anstop++] = p[cur++].id;        }        printf("%d",anstop);        for(int i = 0; i < anstop; ++i){            printf(" %d",ans[i]);        }        printf("\n");    }    return 0;}poj3347Kadj Squares//非常没素质的一道讨论题,不想写。/*POJ 2826An Easy Problem?!*//* 重点不在easy problem,在于后面的两个标点符号。*哥见的easy problem多了,大都很难,鄙视出题人!这题情况很多,要慢慢讨论:*discuss有一个比较好的:*找出交点P*统计4个点有多少个比p点高,要有两个点a和b才行,比较矮的那个交点a向上的垂直射线是否与高的那点b所在的线是否相交*不想交就用叉积求面积。*/#include <cstdio>#include <cstring>#include <cmath>using namespace std;#define max(a,b) ((a)>(b) ? (a) : (b))#define min(a,b) ((a)<(b) ? (a) : (b))#define fsm(a,b) ((b) > EPS+(a)) //a < b#define fbgeq(a,b) ((a) >= (b)-EPS)  //a >= b#define fsmeq(a,b) ((b) >= (a)-EPS)  //a <= b#define EPS 1e-8#define feq(a,b) (fabs((a)-(b))<EPS)#define fbg(a,b) ((a) > EPS+(b))struct Point{    double x,y;    Point(){}    Point(double _x,double _y):x(_x),y(_y){}    void input(){        scanf("%lf%lf",&x,&y);    }};struct Segment{    Point a,b;    Segment(){}    Segment(Point _a,Point _b):a(_a),b(_b){}};struct Line{    double a,b,c;    Line(){}    Line(double _a,double _b,double _c):a(_a),b(_b),c(_c){}};inline double difcross(Point a,Point b,Point c){    return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);}inline void getline(Point p1,Point p2,Line &l){        l.a = p2.y - p1.y;        l.b = p1.x - p2.x;        l.c = p1.y*p2.x - p1.x*p2.y;        if (l.a < 0) l.a *= -1,l.b *= -1,l.c *= -1;}inline bool line_intersect(Line l1,Line l2,Point &p){    double d=l1.a*l2.b-l2.a*l1.b;    if (feq(d, 0)) return 0;    p.x = (l2.c*l1.b-l1.c*l2.b)/d;    p.y = (l2.a*l1.c-l1.a*l2.c)/d;    return true;}inline bool SegIntersect(Segment s1,Segment s2){    if (fabs(difcross(s1.a, s2.a, s2.b)) < EPS &&        fabs(difcross(s1.b, s2.a, s2.b)) < EPS) return 0;    double mxs1x = max(s1.a.x,s1.b.x), mns1x = min(s1.a.x,s1.b.x);    double mxs2x = max(s2.a.x,s2.b.x), mns2x = min(s2.a.x,s2.b.x);    double mxs1y = max(s1.a.y,s1.b.y), mns1y = min(s1.a.y,s1.b.y);    double mxs2y = max(s2.a.y,s2.b.y), mns2y = min(s2.a.y,s2.b.y);    return fsmeq(difcross(s1.a,s1.b,s2.a)*difcross(s1.a,s1.b,s2.b), 0)&&           fsmeq(difcross(s2.a,s2.b,s1.a)*difcross(s2.a,s2.b,s1.b), 0)&&           fbgeq(mxs1x, mns2x)&&fbgeq(mxs2x, mns1x) &&           fbgeq(mxs1y, mns2y)&&fbgeq(mxs2y, mns1y);}inline double trarea(Point a,Point b,Point c){    return   fabs(difcross(a,b,c))/2.0;}int main(){    int n;    scanf("%d",&n);    Point a,b,c,d,cross;    while(n --){        double ans;        a.input();        b.input();        c.input();        d.input();        double y1 = max(a.y,b.y);        double y2 = max(c.y,d.y);        Segment s1,s2;        if(fbg(y1,y2)){            s1 = Segment(c,d);            s2 = Segment(a,b);        }        else{            s1 = Segment(a,b);            s2 = Segment(c,d);        }        if(!SegIntersect(s1,s2)){            printf("0.00\n");            continue;        }        Line l1,l2;        getline(a,b,l1);        getline(c,d,l2);        line_intersect(l1,l2,cross);        int cnt = 0;        if(fbg(a.y,cross.y))cnt ++;        if(fbg(b.y,cross.y))cnt ++;        if(fbg(c.y,cross.y))cnt ++;        if(fbg(d.y,cross.y))cnt ++;        if(cnt < 2){            printf("0.00\n");            continue;        }        Point tmp = fbg(s1.a.y,s1.b.y) ? s1.a : s1.b;        Line l3 = Line(0,1,-tmp.y);        Point pp;        getline(s2.a,s2.b,l2);        line_intersect(l2,l3,pp);        Segment s3 = Segment(tmp,Point(tmp.x,1e100));        if(SegIntersect(s2,s3)){            printf("0.00\n");            continue;        }        ans = trarea(tmp,cross,pp);        printf("%.2lf\n",ans);    }    return 0;}/*POJ 1039 Pipe*/ //恶心的枚举,容易错,注意叉乘的性质,精度1e-3或者不要都可以#include <cstdio>#include <cstring>#include <cmath>using namespace std;#define EPS 1e-6#define max(a,b) ((a)>(b) ? (a) : (b))#define min(a,b) ((a)<(b) ? (a) : (b))#define a2r(a) (((a)*PI)/180.0)//角度到弧度#define r2a(a) (((a)/PI)*180.0)//弧度到角度#define feq(a,b) (fabs((a)-(b))<EPS)//a==b#define fbg(a,b) ((a) > EPS+(b)) //a > b#define fsm(a,b) ((b) > EPS+(a)) //a < b#define fsmeq(a,b) ((b) >= (a)-EPS)  //a <= bconst int MAXN = 30;struct Point{    double x,y;    Point(){}    Point(double _x,double _y):x(_x),y(_y){}    void input(){        scanf("%lf%lf",&x,&y);    }};Point psa[MAXN],psb[MAXN];struct Segment{    Point a,b;    Segment(){}    Segment(Point _a,Point _b):a(_a),b(_b){}};struct Line{    double a,b,c;    Line(){}    Line(double _a,double _b,double _c):a(_a),b(_b),c(_c){}};inline double difcross(Point a,Point b,Point c){    return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);}inline int SegLineIntersect(Point s1,Point s2,Point e1,Point e2){    if(difcross(e1,e2,s1)*difcross(e1,e2,s2) <= 0)return 1;    return 0;}inline void getline(Point p1,Point p2,Line &l){        l.a = p2.y - p1.y;        l.b = p1.x - p2.x;        l.c = p1.y*p2.x - p1.x*p2.y;        if (l.a < 0) l.a *= -1,l.b *= -1,l.c *= -1;}inline bool line_intersect(Line l1,Line l2,Point &p){    double d=l1.a*l2.b-l2.a*l1.b;    if (feq(d, 0)) return 0;    p.x = (l2.c*l1.b-l1.c*l2.b)/d;    p.y = (l2.a*l1.c-l1.a*l2.c)/d;    return true;}int n;int main(){    while(scanf("%d",&n) != EOF){        if(n == 0)break;        double ans = -1e100;        for(int i = 0; i < n; ++i){            psa[i].input();            psb[i] = Point(psa[i].x,psa[i].y-1);        }        Line l1,l2,l3,l;        Point cross;        Segment s1,s2;        for(int i = 0; i < n; ++i){            for(int j = 0; j < n; ++j){                if(i == j)continue;                int k = max(i,j);                int tag;                getline(psa[i],psb[j],l);                for(tag = 0; tag < n; tag++){                    if(fsmeq(difcross(psa[i],psa[tag],psb[j])*                        difcross(psa[i],psb[tag],psb[j]),0))                        continue;                    else break;                }                if(tag < k)continue;                if(tag == n){                    ans = psa[n-1].x;                    break;                }                if(SegLineIntersect(psa[tag-1],psa[tag],psa[i],psb[j])){                    getline(psa[tag-1],psa[tag],l1);                    line_intersect(l1,l,cross);                    if(ans < cross.x)ans = cross.x;                }                if(SegLineIntersect(psb[tag-1],psb[tag],psa[i],psb[j])){                    getline(psb[tag-1],psb[tag],l1);                    line_intersect(l1,l,cross);                    if(ans < cross.x)ans = cross.x;                }            }        }        if(ans == psa[n-1].x)puts("Through all the pipe.");       else  printf("%.2lf\n",ans);    }    return 0;}/*POJ 3449 Geometric Shapes*///堪称屎上第一屎的题目,输入输出都很烦,判断几何体是否相交///没见过输入输出这么没素质的,光输入输出处理了100多行,没办法,谁让咱不是出题的。//其实就利用了一个线段相交判断,还有一个就是已知正方形的对角线上两个点,求出另外两个点的坐标#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>using namespace std;#define EPS 1e-16#define max(a,b) ((a)>(b) ? (a) : (b))#define min(a,b) ((a)<(b) ? (a) : (b))#define feq(a,b) (fabs((a)-(b))<EPS)//a==b#define fbg(a,b) ((a) > EPS+(b)) //a > b#define fsm(a,b) ((b) > EPS+(a)) //a < b#define fbgeq(a,b) ((a) >= (b)-EPS)  //a >= b#define fsmeq(a,b) ((b) >= (a)-EPS)  //a <= bconst int MAXN = 30;struct Point{    double x,y;    Point(){}    Point(double _x,double _y):x(_x),y(_y){}    void input(){        scanf("%lf%lf",&x,&y);    }};struct Segment{    Point a,b;    Segment(){}    Segment(Point _a,Point _b):a(_a),b(_b){}};struct Thing{    char tag;    Point p[25];    char op[20];    int n;    inline int input(){        scanf(" %c",&tag);        if(tag == '.')return -1;        if(tag == '-')return 0;        scanf(" %s",op);        if(!strcmp(op,"square")){            n = 4;            scanf(" (%lf,%lf)",&p[1].x,&p[1].y);            scanf(" (%lf,%lf)",&p[3].x,&p[3].y);             Point b, d;            double x,y,mx, my;            mx = (p[1].x+p[3].x)/2.0, my = (p[1].y+p[3].y)/2.0;            x = p[1].x - mx;    y = p[1].y - my;            p[2].x = -y + mx;   p[2].y = x + my;            p[4] = Point(p[1].x+p[3].x-p[2].x,p[1].y+p[3].y-p[2].y);            p[0] = p[4];        }        else if(!strcmp(op,"triangle")){            n = 3;            scanf(" (%lf,%lf)",&p[1].x,&p[1].y);            scanf(" (%lf,%lf)",&p[2].x,&p[2].y);            scanf(" (%lf,%lf)",&p[3].x,&p[3].y);            p[0] = p[3];        }        else if(!strcmp(op,"line")) {            n = 2;            scanf(" (%lf,%lf)",&p[1].x,&p[1].y);            scanf(" (%lf,%lf)",&p[2].x,&p[2].y);            p[0] = p[2];        }        else if(!strcmp(op,"rectangle")){            n = 4;            scanf(" (%lf,%lf)",&p[1].x,&p[1].y);            scanf(" (%lf,%lf)",&p[2].x,&p[2].y);            scanf(" (%lf,%lf)",&p[3].x,&p[3].y);            p[4] = Point(p[1].x+p[3].x-p[2].x,p[1].y+p[3].y-p[2].y);            p[0] = p[4];        }        else if(!strcmp(op,"polygon")){            scanf("%d",&n);            for(int i = 1; i <= n; ++i)                scanf(" (%lf,%lf)",&p[i].x,&p[i].y);            p[0] = p[n];        }        return 1;    }};inline double difcross(Point a,Point b,Point c){    return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);}inline bool SegIntersect(Segment s1,Segment s2){    double mxs1x = max(s1.a.x,s1.b.x), mns1x = min(s1.a.x,s1.b.x);    double mxs2x = max(s2.a.x,s2.b.x), mns2x = min(s2.a.x,s2.b.x);    double mxs1y = max(s1.a.y,s1.b.y), mns1y = min(s1.a.y,s1.b.y);    double mxs2y = max(s2.a.y,s2.b.y), mns2y = min(s2.a.y,s2.b.y);    return fsmeq(difcross(s1.a,s1.b,s2.a)*difcross(s1.a,s1.b,s2.b), 0)&&           fsmeq(difcross(s2.a,s2.b,s1.a)*difcross(s2.a,s2.b,s1.b), 0)&&           fbgeq(mxs1x, mns2x)&&fbgeq(mxs2x, mns1x) &&           fbgeq(mxs1y, mns2y)&&fbgeq(mxs2y, mns1y);}inline bool Intersect(Thing a,Thing b){    int flag = 0;    Segment s1,s2;    for(int i = 0; i < a.n; ++i){        for(int j = 0; j < b.n; ++j){            s1 = Segment(a.p[i],a.p[i+1]);            s2 = Segment(b.p[j],b.p[j+1]);            if(SegIntersect(s1,s2))return 1;        }    }    return 0;}inline int cmp(Thing a,Thing b){    return a.tag < b.tag;}Thing things[MAXN];char ans[MAXN];int main(){    int top;    Thing tmp;    while(tmp.input() != -1){        if(tmp.tag == '-')continue;        top = 0;        things[top] = tmp;        while(tmp.input() != 0){            things[++top] = tmp;        }        top ++;        sort(things,things+top,cmp);        for(int i = 0; i < top; ++i){            int t = 0;            printf("%c ",things[i].tag);            for(int j = 0; j < top; ++j){                if(i == j)continue;                if(Intersect(things[i],things[j])){                    ans[t++] = things[j].tag;                }            }            if(t == 0)                puts("has no intersections");            else if(t == 1)                printf("intersects with %c\n",ans[0]);            else if(t == 2)                printf("intersects with %c and %c\n",ans[0],ans[1]);            else{                printf("intersects with ");                for(int j = 0; j < t - 1; ++j)                    printf("%c, ",ans[j]);                printf("and %c\n",ans[t-1]);            }        }        puts("");    }    return 0;}/*POJ 1584 A Round Peg in a Ground Hole*///这题用的东西很多,包括点到直线距离,圆与多边形相交(圆在多边形内判断),判断多边形是否为凸多边形/*关于圆在多边形内判断,要先判断圆心是否在多边形内,这个我是套的点在多边形内的模板,对于凸多边形,有一种特定的方法去判断(这样的话代码长度会大大缩短):点在已知凸包内(包括三点共线)====》其对于所有边的叉乘同大于等于0或小于等于0;本人代码仅供个人观赏。一般人看不懂。*/#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>using namespace std;#define INF 1e100#define EPS 1e-8#define PI acos(-1.0)#define max(a,b) ((a)>(b) ? (a) : (b))#define min(a,b) ((a)<(b) ? (a) : (b))#define feq(a,b) (fabs((a)-(b))<EPS)//a==b#define fbg(a,b) ((a) > EPS+(b)) //a > b#define fsm(a,b) ((b) > EPS+(a)) //a < b#define fbgeq(a,b) ((a) >= (b)-EPS)  //a >= b#define fsmeq(a,b) ((b) >= (a)-EPS)  //a <= bconst int MAXN = 100010;struct Point{    double x,y;    Point(){}    Point(double _x,double _y):x(_x),y(_y){}    void input(){        scanf("%lf%lf",&x,&y);    }};struct Segment{    Point a,b;    Segment(){}    Segment(Point _a,Point _b):a(_a),b(_b){}};struct Circle{    Point cer;    double radious;    Circle(){}    Circle(Point _cer,double _radious):cer(_cer),radious(_radious){}    void input(){        scanf("%lf",&radious);        cer.input();    }};struct Line{    double a,b,c;     Line(){}    Line(double _a,double _b,double _c):a(_a),b(_b),c(_c){}};inline double pdis(Point a,Point b){    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}inline double difcross(Point a,Point b,Point c){    return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);}inline double p2seg(Point a,Point p1,Point p2){    return fabs(difcross(a,p1,p2))/pdis(p1,p2);}inline bool SegIntersect(Segment s1,Segment s2){    if (fabs(difcross(s1.a, s2.a, s2.b)) < EPS &&        fabs(difcross(s1.b, s2.a, s2.b)) < EPS) return 0;    double mxs1x = max(s1.a.x,s1.b.x), mns1x = min(s1.a.x,s1.b.x);    double mxs2x = max(s2.a.x,s2.b.x), mns2x = min(s2.a.x,s2.b.x);    double mxs1y = max(s1.a.y,s1.b.y), mns1y = min(s1.a.y,s1.b.y);    double mxs2y = max(s2.a.y,s2.b.y), mns2y = min(s2.a.y,s2.b.y);    return fsmeq(difcross(s1.a,s1.b,s2.a)*difcross(s1.a,s1.b,s2.b), 0)&&           fsmeq(difcross(s2.a,s2.b,s1.a)*difcross(s2.a,s2.b,s1.b), 0)&&           fbgeq(mxs1x, mns2x)&&fbgeq(mxs2x, mns1x) &&           fbgeq(mxs1y, mns2y)&&fbgeq(mxs2y, mns1y);}inline int PonSeg(Point a,Point p1,Point p2){    if(fabs(difcross(a,p1,p2)) <= EPS && a.x >= min(p1.x,p2.x)&& a.x <= max(p1.x,p2.x)       && a.y >= min(p1.y,p2.y) && a.y <= max(p1.y,p2.y))       return 1;    return 0;}#define on_s2r(p, s) (feq(p.y, s.y) && fbgeq(p.x, s.x))inline int p_in_polygon(Point a,Point p[],int np){  //点a是否在点数为np的多边形内    int count = 0;    Segment s,ps;    ps.a = a,ps.b = a;    ps.b.x = INF;    for(int i = 0;i < np;i++){        s.a = p[i];        if(i + 1 < np)s.b = p[i+1];        else s.b = p[0];        if (s.a.y > s.b.y)swap(s.a,s.b);        if (PonSeg(a,s.a,s.b))return 2;        if (!feq(s.a.y, s.b.y)){            if (on_s2r(s.b, a)) count++;            else if (!on_s2r(s.a, a) && SegIntersect(s,ps))count++;        }    }    if (count%2)return 1;    return 0;}/*对于凸多边形,还可以这样判断(代替普通的射线法求点在多边形内):inline int p_in_polygon(Point a,Point p[],int np){    p[np] = p[0];    p[np+1] = p[1];    for(int i = 0; i < np; ++i){        double tmp = difcross(a,p[i],p[i+1])*difcross(a,p[i+1],p[i+2]);        if(tmp < -EPS)return 0;    }    return 1;}*/inline bool cir_in_polygon(Circle a,Point ps[],int np){    int ans = p_in_polygon(a.cer,ps,np);    if(ans == 0)return 0;    double mi = INF;    ps[np] = ps[0];    for(int i = 0; i < np; ++i){        double t = p2seg(a.cer,ps[i],ps[i+1]);        mi = min(mi,t);    }    if(fbgeq(mi,a.radious))return 1;    return 0;}inline bool isTu(Point ps[],int n){    ps[n] = ps[0];    for(int i = 0; i < n; ++i){        for(int j = 0; j < n; ++j){            double tmp = difcross(ps[i],ps[i+1],ps[j])*difcross(ps[i],ps[i+1],ps[j+1]);            if(tmp < -EPS)return 0;        }    }    return 1;}int main(){    Circle a;    Point ps[MAXN];    int n;    while(scanf("%d",&n) != EOF){        if(n < 3)break;        a.input();        for(int i = 0; i < n; ++i)ps[i].input();        if(!isTu(ps,n)){            puts("HOLE IS ILL-FORMED");            continue;        }        if(cir_in_polygon(a,ps,n)){            puts("PEG WILL FIT");            continue;        }        puts("PEG WILL NOT FIT");    }    return 0;}/*POJ 2074 Line of Sight*///鄙视好多trick的题,特别是有trick的计算几何题,障碍物可能在房子以上或者线以下,然后注意直线和线段不相交的时候的情况//有好几种 ,我的代码很长,应该是方法不好,因为我先求的是被覆盖的区间然后处理的#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>using namespace std;#define EPS 1e-8#define max(a,b) ( (a) > (b) ? (a) : (b) )#define min(a,b) ( (a) < (b) ? (a) : (b) )#define feq(a,b) (fabs((a)-(b))<EPS)//a==b#define fbg(a,b) ((a) > EPS+(b)) //a > b#define fsm(a,b) ((b) > EPS+(a)) //a < b#define fbgeq(a,b) ((a) >= (b)-EPS)  //a >= b#define fsmeq(a,b) ((b) >= (a)-EPS)  //a <= bconst int MAXN = 1000;struct Point{    double x,y;    Point(){}    Point(double _x,double _y):x(_x),y(_y){}    void input(){        scanf("%lf%lf",&x,&y);    }};struct Line{    double a,b,c;    Line(){}    Line(double _a,double _b,double _c):a(_a),b(_b),c(_c){}};Line tmp,line;inline double difcross(Point a,Point b,Point c){    return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);}inline void getline(Point p1,Point p2,Line &l){        l.a = p2.y - p1.y;        l.b = p1.x - p2.x;        l.c = p1.y*p2.x - p1.x*p2.y;        if (l.a < 0) l.a *= -1,l.b *= -1,l.c *= -1;}inline bool line_intersect(Line l1,Line l2,Point &p){    double d=l1.a*l2.b-l2.a*l1.b;    if (feq(d, 0)) return 0;    p.x = (l2.c*l1.b-l1.c*l2.b)/d;    p.y = (l2.a*l1.c-l1.a*l2.c)/d;    return true;}struct Ans{    double x1,x2;};Ans ans[MAXN];inline int cmp(Ans a,Ans b){    return a.x1 < b.x1;}int main(){    double a,b,c;    Point ha,hb;    Point la,lb;    while(scanf("%lf%lf%lf",&a,&b,&c) != EOF){        if(a == 0 && b == 0 && c == 0)break;        ha = Point(a,c);        hb = Point(b,c);        scanf("%lf%lf%lf",&a,&b,&c);        la = Point(a,c);        lb = Point(b,c);        getline(la,lb,line);        int n;        Point ta,tb,tt;        scanf("%d",&n);        bool flag = 0;        for(int i = 0; i < n; ++i){//直接求的直线与直线相交            scanf("%lf%lf%lf",&a,&b,&c);            if(fsmeq(ha.y,c)||fsmeq(c,la.y)){                    ans[i].x1 = ans[i].x2 = lb.x;                    continue;            }            ta = Point(a,c);            tb = Point(b,c);            getline(ha,tb,tmp);            line_intersect(tmp,line,tt);            ans[i].x2 = tt.x;            getline(hb,ta,tmp);            line_intersect(tmp,line,tt);            ans[i].x1 = tt.x;        }        sort(ans,ans+n,cmp);        double cur = la.x;        double res = 0;        int t = 0;        while(t < n){            if(fsm(res,ans[t].x1-cur))                res = ans[t].x1-cur;            cur = max(cur,ans[t].x2);            t ++;        }        if(fsm(res,lb.x-cur))res = lb.x-cur;        if(feq(res,0))printf("No View\n");        else printf("%.2lf\n",res);    }}二、凸包问题/*POJ 1113 Wall*///裸的凸包,可以做模板#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>using namespace std;#define max(a,b) ((a) > (b) ? (a) : (b))#define min(a,b) ((a) < (b) ? (a) : (b))#define EPS 1e-8#define PI acos(-1.0)#define feq(a,b) (fabs((a)-(b))<EPS)//a==b#define fbg(a,b) ((a) > EPS+(b)) //a > b#define fsm(a,b) ((b) > EPS+(a)) //a < b#define fbgeq(a,b) ((a) >= (b)-EPS)  //a >= b#define fsmeq(a,b) ((b) >= (a)-EPS)  //a <= bconst int MAXN = 1000;struct Point{    double x,y;    Point(){}    Point(double _x,double _y):x(_x),y(_y){}    void input(){        scanf("%lf%lf",&x,&y);    }};inline double pdis(Point a,Point b){    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}inline double difcross(Point a,Point b,Point c){    return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);}Point p0;int top,n,graham[MAXN];Point points[MAXN];inline int cmp(Point a, Point b){    double k = difcross(p0, a, b);    if(feq(k,0) && fbg(pdis(a, p0) , pdis(b, p0)))return 1;    else if( k > EPS ) return 1;     return 0;}inline void Graham(){        int i,u = 0;        for(i = 1; i < n; i++){            if(fsm(points[i].y , points[u].y)||feq(points[i].y , points[u].y)&&fsm(points[i].x , points[u].x) )u = i;        }        swap(points[0],points[u]);        p0 = points[0];        sort( points+1, points + n, cmp );        graham[0] = 0;        graham[1] = 1;        graham[2] = 2;        top = 2;        for( i = 3; i < n; i++){            while(difcross(points[i],points[graham[top]],points[graham[top-1]])                   > EPS){                top--;                if(top == 0)break;            }            graham[++top] = i;        }}double ans,R;inline void solve(){    Graham();    ans = 0;    for(int i = 0; i < top; ++i){        ans += pdis(points[graham[i]],points[graham[i+1]]);    }    ans += pdis(points[graham[0]],points[graham[top]]);    ans += 2.0*PI*R;    printf("%.0lf\n",ans);}int main(){    scanf("%d%lf",&n,&R);    for(int i = 0; i < n; ++i)        points[i].input();    solve();}/*POJ 2007 Scrambled Polygon *///求凸包的过程中极角排序这个思想的应用,非常重要,注意sort中的cmp怎么写的#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>using namespace std;#define max(a,b) ((a) > (b) ? (a) : (b))#define min(a,b) ((a) < (b) ? (a) : (b))#define EPS 1e-8#define PI acos(-1.0)#define feq(a,b) (fabs((a)-(b))<EPS)//a==b#define fbg(a,b) ((a) > EPS+(b)) //a > b#define fsm(a,b) ((b) > EPS+(a)) //a < b#define fbgeq(a,b) ((a) >= (b)-EPS)  //a >= b#define fsmeq(a,b) ((b) >= (a)-EPS)  //a <= bconst int MAXN = 55;struct Point{    double x,y;    Point(){}    Point(double _x,double _y):x(_x),y(_y){}    void input(){        scanf("%lf%lf",&x,&y);    }};inline double pdis(Point a,Point b){    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}inline double difcross(Point a,Point b,Point c){    return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);}Point p0;int n;Point points[MAXN];inline int cmp(Point a, Point b){    double k = difcross(p0, a, b);    if(feq(k,0) && fbg(pdis(a, p0) , pdis(b, p0)))return 1;    else if( k > EPS ) return 1;     return 0;}int main(){    int top = 0;    double x0,y0;    while(scanf("%lf%lf",&x0,&y0) != EOF){        //if(x0 == -1 && y0 == -1)break;        points[top++] = Point(x0,y0);    }    p0 = points[0];    sort(points+1,points+1+top,cmp);    for(int i = 0; i < top; ++i)        printf("(%.0lf,%.0lf)\n",points[i].x,points[i].y);    return 0;}/*POJ 1873 The Fortified Forest*///1999年worldfinal的题,纯暴力可以过,用位运算的枚举,枚举出2^n种状态,取最优解法即可。#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>using namespace std;#define EPS 1e-6#define max(a,b) ((a)>(b) ? (a) : (b))#define min(a,b) ((a)<(b) ? (a) : (b))#define feq(a,b) (fabs((a)-(b))<EPS)//a==b#define fbg(a,b) ((a) > EPS+(b)) //a > b#define fsm(a,b) ((b) > EPS+(a)) //a < b#define fbgeq(a,b) ((a) >= (b)-EPS)  //a >= b#define fsmeq(a,b) ((b) >= (a)-EPS)  //a <= bconst int MAXN = 20;double len[MAXN];double val[MAXN];struct Point{    double x,y;    Point(){}    Point(double _x,double _y):x(_x),y(_y){}    void input(){        scanf("%lf%lf",&x,&y);    }};inline double difcross(Point a,Point b,Point c){    return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);}inline double pdis(Point a,Point b){    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}int graham[MAXN],top;Point p0;Point p[MAXN],points[MAXN];inline int cmp(Point a, Point b){    double k = difcross(p0, a, b);    if(feq(k,0) && fbg(pdis(a, p0) , pdis(b, p0)))return 1;    else if( k > EPS ) return 1;     return 0;}inline void Graham(Point points[],int n){        if(n < 3){            if(n == 0 || n == 1)top = 0;            if(n == 2)top = 1;            return;        }        int i,u = 0;        for(i = 1; i < n; i++){            if(fsm(points[i].y , points[u].y)||feq(points[i].y , points[u].y)&&fsm(points[i].x , points[u].x) )u = i;        }        swap(points[0],points[u]);        p0 = points[0];        sort( points+1, points + n, cmp );        graham[0] = 0;        graham[1] = 1;        graham[2] = 2;        top = 2;        for( i = 3; i < n; i++){            while(difcross(points[i],points[graham[top]],points[graham[top-1]])> EPS){                top--;                if(top == 0)break;            }            graham[++top] = i;        }}inline double girth(){        double ans = 0;        for(int i = 0; i < top ; ++i){            ans += pdis(points[graham[i]],points[graham[i+1]]);        }        ans += pdis(points[graham[top]],points[graham[0]]);        return ans;}int main(){    int n;    int cas = 0;    while(scanf("%d",&n) != EOF){        if(n == 0)break;        cas ++;        if(cas != 1)puts("");        for(int i = 0; i < n; ++i){            p[i].input();            scanf("%lf",&val[i]);            scanf("%lf",&len[i]);        }        int tn = 1<<n;        double ans = 1e100,tans;        int res = 0;        for(int tag = 0; tag < tn; tag ++){            int tt = 0;double tlen = 0,tval = 0;            for(int j = 0; j < n; ++j){                int t = 1<<j;                if(t&tag)                    points[tt++] = p[j];                else {                    tlen += len[j];                    tval += val[j];                }            }            Graham(points,tt);            double need_len = girth();            if(fbgeq(tlen,need_len) && fbg(ans,tval)){                ans = tval;                res = tag;                tans = tlen - need_len;            }        }        printf("Forest %d\n",cas);        printf("Cut these trees:");        for(int j = 0; j < n; ++j){            if((1<<j)&res)continue;            printf(" %d",j+1);        }        puts("");        printf("Extra wood: %.2lf\n",tans);    }    return 0;}/*POJ 1228 Grandpa's Estate*///题意比较难理解,给n个凸多边形上的点,问能不能唯一确定这个凸多边形。//刚写凸包的时候写的这个题,代码风格和现在很不一样/*这是这题的做法,黑书上的题1. n<=5,一律输出NO2. 所有点共线,NO3. 凸包上每条边上至少有三点,否则NO*/#include<iostream>#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;#define eps 1e-8#define MAXN 1005#define zero(x) (((x)>0?(x):-(x))<eps)struct point{    double x,y;};point P[MAXN],convex[MAXN];int t,n,i,j,flag[MAXN],k;double xmult(point p1,point p2,point p0){    return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);}point p1,p2;int graham_cp(const void* a,const void* b){    double ret=xmult(*((point*)a),*((point*)b),p1);    return zero(ret)?(xmult(*((point*)a),*((point*)b),p2)>0?1:-1):(ret>0?1:-1);}void _graham(int n,point* p,int& s,point* ch){    int i,k=0;    for (p1=p2=p[0],i=1;i<n;p2.x+=p[i].x,p2.y+=p[i].y,i++)        if (p1.y-p[i].y>eps||(zero(p1.y-p[i].y)&&p1.x>p[i].x))            p1=p[k=i];    p2.x/=n,p2.y/=n;    p[k]=p[0],p[0]=p1;    qsort(p+1,n-1,sizeof(point),graham_cp);    for (ch[0]=p[0],ch[1]=p[1],ch[2]=p[2],s=i=3;i<n;ch[s++]=p[i++])        for (;s>2&&xmult(ch[s-2],p[i],ch[s-1])<-eps;s--);}int graham(int n,point* p,point* convex,int maxsize=0,int dir=1){    point* temp=new point[n];    int s,i;    _graham(n,p,s,temp);    for (convex[0]=temp[0],n=1,i=(dir?1:(s-1));dir?(i<s):i;i+=(dir?1:-1))        if (maxsize||!zero(xmult(temp[i-1],temp[i],temp[(i+1)%s])))            convex[n++]=temp[i];    delete []temp;    return n;}int dot_online_in(point p,point l1,point l2){    return zero(xmult(p,l1,l2))&&(l1.x-p.x)*(l2.x-p.x)<eps&&(l1.y-p.y)*(l2.y-p.y)<eps;}int main(){    scanf("%d",&t);    while(t--)    {        scanf("%d",&n);        for(i=0;i<n;i++)        {            scanf("%lf %lf",&P[i].x,&P[i].y);        }        if(n<=5)        {            printf("NO\n");            continue;        }        k=0;        for(i=1;i<n-1;i++)        {            if(xmult(P[0],P[n-1],P[i])!=0)            {                k=1;                break;            }        }        if(!k)        {            printf("NO\n");            continue;        }        int M=graham(n,P,convex,0,1);        if(M==n)        {            printf("NO\n");            continue;        }        memset(flag,0,sizeof(flag));        for(i=0;i<n;i++)        {            for(j=0;j<M-1;j++)            {                if(dot_online_in(P[i],convex[j],convex[j+1]))                {                    flag[j]++;                }            }            if(dot_online_in(P[i],convex[M-1],convex[0]))            {                flag[M-1]++;            }        }        k=0;        for(i=0;i<M;i++){            if(flag[i]<3){                k=1;                break;            }        }        if(!k)            printf("YES\n");        else printf("NO\n");    }    return 0;}/*POJ 3348 Cows *///求凸包面积#include<iostream>#include<string.h>#include<stdio.h>#include<string.h>#include<cmath>#include<algorithm>using namespace std;const int maxn = 10010;struct Point {double x;double y;};Point p[maxn];int n;double pdis(Point a,Point b){return sqrt((a.x - b.x)*(a.x - b.x)+(a.y - b.y)*(a.y - b.y));}double det(Point p0,Point p1,Point p2){return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y - p0.y);}int cmp(Point a,Point b){double k = det(p[0],a,b);if(k > 0)return 1;else if(k == 0 && pdis(p[0],a) - pdis(p[0],b) > 0)return 1;return 0;}int graham[maxn];int top;void Graham(){int i,u = 0;for(i = 1; i < n; i++){if(p[i].y < p[u].y || (p[i].y == p[u].y && p[i].x < p[u].x))u = i;}Point t;t.x = p[u].x;t.y = p[u].y;p[u] = p[0];p[0] = t;sort(p+1,p+n,cmp);graham[0] = 0;graham[1] = 1;graham[2] = 2;top = 2;for(i = 3; i < n; i++){while(det(p[i],p[graham[top]],p[graham[top-1]]) > 0){top--;if(top == 0)break;}graham[++top] = i;}}int main(){scanf("%d",&n);for(int i = 0; i < n; i++){scanf("%lf%lf",&p[i].x,&p[i].y);}double area = 0;Graham();Point t;t.x = 0.000;t.y = 0.000;for(int i = 0; i < top; i++){area += det(t,p[graham[i]],p[graham[i+1]]);}area += det(t,p[graham[top]],p[graham[0]]);area = fabs(area)/2;area /= 50;int ans = int(area);printf("%d\n",ans);return 0;}三、面积问题,公式问题/*POJ 1654 Area *///多边形面积计算,利用叉积,水题#include <cstdio>#include <cstring>using namespace std;struct p{       int x,y;};int square(p a,p b,p c){      int r = (b.x-a.x)*(c.y-b.y)-(b.y-a.y)*(c.x-b.x);      return r;}int main(){    int n;    int move[10][2]={{0,0},{-1,-1},{0,-1},{1,-1},{-1,0},{0,0},{1,0},{-1,1},{0,1},{1,1}        };    scanf("%d",&n);    char ch[1000100];    while(n--)    {        scanf("%s",ch);        int len = strlen(ch);        int i,j,k;        p a,b,c;        a.x=0,a.y=0;        c.x=a.x+move[ch[0]-'0'][0];        c.y=a.y+move[ch[0]-'0'][1];        __int64 s =0;        for(i=1;i<len;i++)        {                   b=c;                   c.x=b.x+move[ch[i]-'0'][0];                   c.y=b.y+move[ch[i]-'0'][1];                   s+=square(a,b,c);        }        if(s<0)s=-s;        printf("%I64d",s/2);        if(s%2)        printf(".5");        printf("\n");    }    return 0;}/*POJ 1265 Area *//*利用Pick定理,Pick定理是说,假设平面上有一个顶点全在格点上的多边形P,那么其面积S(P)应该等于i+b/2-1,其中i为多边形内部所含的格点数,b是多边形边界上的格点数。关于pick定理的证明,这里有一个http://www.matrix67.com/blog/archives/768*///求边上有多少个格点的时候用最大公约数#include<cstring>#include<cmath>#include<cstdio>using namespace std;struct point{double x,y;};int gcd(int a,int b){    if(b == 0)return a;    else return gcd(b,a%b);}double area_polygon(int n,point* p){double s1=0,s2=0;int i;for (i=0;i<n;i++)s1+=p[(i+1)%n].y*p[i].x,s2+=p[(i+1)%n].y*p[(i+2)%n].x;return fabs(s1-s2)/2;}point p[103];int main(){int testcase;int n;int i,j;double I,E,s;int x,y;scanf("%d",&testcase);for(i=1;i<=testcase;i++){E=0;scanf("%d",&n);point temp;temp.x=temp.y=0;p[0]=temp;double dx,dy;for(j=1;j<=n;j++){scanf("%lf%lf",&dx,&dy);temp.x+=dx;temp.y+=dy;p[j]=temp;}s=area_polygon(n,p);for(j=1;j<n;j++)E+=gcd((int)(abs(p[j].x-p[j-1].x)+0.1),(int)(abs(p[j].y-p[j-1].y)+0.1));E+=gcd((int)(abs(p[n-1].x-p[0].x)+0.1),(int)(abs(p[n-1].y-p[0].y)+0.1));I=s+1-E/2;printf("Scenario #%d:\n",i);printf("%.0lf %.0lf %.1lf\n\n",I,E,s);}return 0;}/*POJ 2954 Triangle*///Pick定理的应用#include <cstdio>#include <cstring>#include <cmath>using namespace std;struct Point{    double x,y;    void input(){        scanf("%lf%lf",&x,&y);    }};Point a,b,c;inline int Input(){    a.input();    b.input();    c.input();    if(a.x == 0 && b.x == 0 && c.x == 0    && a.y == 0 && b.y == 0 && c.y == 0)return 0;    return 1;}inline double difcross(Point a,Point b,Point c){    return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);}inline double trarea(Point a,Point b,Point c){    return   fabs(difcross(a,b,c))/2.0;}inline int gcd(int a,int b){    if(b == 0)return a;    else return gcd(b,a%b);}int main(){    while(Input()){        double area = trarea(a,b,c);        double E = 0;        E += gcd((int)fabs(a.x-b.x),(int)fabs(a.y-b.y));        E += gcd((int)fabs(b.x-c.x),(int)fabs(b.y-c.y));        E += gcd((int)fabs(c.x-a.x),(int)fabs(c.y-a.y));        double ans = area+1-E/2;        printf("%.0lf\n",ans);    }    return 0;}四、半平面交关于半平面交,见下下一篇文章《半平面交》文章里关于半平面交的所有的题目都有五、计算几何背景,实际上解题的关键是其他问题(数据结构、组合数学,或者是 枚举思想)若干道经典的离散化+扫描线的题目,ACM选手必做题目这一部分比较难,涉及到各种数据结构,各种思想,主要不在计算几何,先空着。/*POJ 2002 Squares*///给若干个点,问能组成多少个正方形,hash可以解决#include <cstdio>#include <cstring>#include<cmath>#include<vector>#include<algorithm>using namespace std;struct seg{int x,y;};seg points[2010];vector < seg  > hash[40010];int find(int x1,int y1){int t = abs((x1+y1)/2);int flag = 0;for(int i = 0; i < hash[t].size(); i++){seg tq = hash[t][i];if(tq.x == x1 && tq.y == y1){flag = 1;break;}}return flag;}int main(){int n,i,j;while(scanf("%d",&n)!=EOF){        if(n == 0)break;int cnt = 0;int x,y;for(i = 0; i <= 40000; i++)hash[i].clear();for(i = 0; i < n; i++){scanf("%d%d",&x,&y);                points[i].x = x;points[i].y = y;int mid = abs((x+y)/2);if(!find(x,y))hash[mid].push_back(points[i]);}int a1,b1,a2,b2,x1,y1,x2,y2;for(i = 0; i < n; i++){for(j = i+1; j < n; j++){a1 = points[i].x;a2 = points[i].y;b1 = points[j].x;b2 = points[j].y;x1 = a1 + b2 - a2;y1 = a2 - b1 + a1;x2 = b1 + b2 - a2;y2 = b2 - b1 + a1;if(find(x1,y1) && find(x2,y2))cnt++;x1 = a1 - b2 + a2;y1 = a2 + b1 - a1;x2 = b1 - b2 + a2;y2 = b2 + b1 - a1;if(find(x1,y1) && find(x2,y2))cnt++;}}printf("%d\n",cnt/4);     }return 0;}六、随机算法/*POJ 2420 A Star not a Tree?*//*第一次做关于随机算法的题目,求多边形的费马点,所谓费马点,就是多边形中的一个点,该点到其他点的距离之和最短,好像只有三角形可以有公式去求费马点,而四边形以上的多边形就要用其他方法了,这个方法就是随机化变步长贪心法、就是选取初始点,然后上下左右向四个方向移动这个点,一直选取最优解,直到上下左右四个方向都不如该点时就OK,然后改变步长继续判断*/#include <cstdio>#include <cstring>#include <cmath>using namespace std;const int MAXN = 1000;struct Point{    double x,y;    Point(){}    Point(double _x,double _y):x(_x),y(_y){}    void input(){        scanf("%lf%lf",&x,&y);    }};Point points[MAXN],tmp;int n;double di[4][2] = {{0,1.0},{0,-1.0},{1.0,0},{-1.0,0}};inline double pdis(Point a,Point b){    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}inline double cal(Point a){    double res = 0;    for(int i = 0; i < n; ++i){        res += pdis(points[i],a);    }    return res;}int main(){    while(scanf("%d",&n) != EOF){        for(int i = 0; i < n; ++i)points[i].input();        Point tt;        tmp = points[0];        double ans = cal(tmp);        double step = 1000;        bool flag = 1;        while(step > 0.2){            flag = 1;            while(flag){                flag = 0;                for(int i = 0; i < 4; ++i){                    tt = Point(tmp.x+di[i][0]*step,tmp.y+di[i][1]*step);                    double caltt = cal(tt);                    if(caltt < ans){                        ans = caltt;                        tmp = tt;                        flag = 1;                    }                }            }            step /= 2;        }        printf("%.0lf\n",ans);    }    return 0;}七、解析几何/*POJ 1375 Intervals *///求圆的切线的一道题,求圆的切点的时候用向量旋转即可#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>using namespace std;#define EPS 1e-8#define max(a,b) ((a)>(b) ? (a) : (b))#define min(a,b) ((a)<(b) ? (a) : (b))#define feq(a,b) (fabs((a)-(b))<EPS)//a==b#define fbg(a,b) ((a) > EPS+(b)) //a > b#define fsm(a,b) ((b) > EPS+(a)) //a < b#define fbgeq(a,b) ((a) >= (b)-EPS)  //a >= b#define fsmeq(a,b) ((b) >= (a)-EPS)  //a <= bconst int MAXN = 1000;struct Point{    double x,y;    Point(){}    Point(double _x,double _y):x(_x),y(_y){}    void input(){        scanf("%lf%lf",&x,&y);    }    void output(){        printf("%lf %lf\n",x,y);    }};struct Node{    double lx,rx;};Point light;inline double pdis(Point a,Point b){    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}inline Point rotate(Point p,double angle){    Point res;    res.x=p.x*cos(angle)-p.y*sin(angle);    res.y=p.x*sin(angle)+p.y*cos(angle);    return res;}inline void GetcutPoint(Point o,double r,Point &res1,Point &res2){    Point t = Point(light.x-o.x,light.y-o.y);    double tmp = r/pdis(o,light);    double angle = acos(tmp);    t.x /= pdis(o,light);    t.y /= pdis(o,light);    t.x *= r;    t.y *= r;    res1 = rotate(t,angle);    res2 = rotate(t,-angle);    res1.x += o.x;res1.y += o.y;    res2.x += o.x;    res2.y += o.y;}inline void getline(Point x,Point y,double &a,double &b,double &c){    a = y.y - x.y;    b = x.x - y.x;    c = y.x * x.y - x.x * y.y;}inline int cmp(Node a,Node b){    return a.lx < b.lx;}int main(){    int n;    while(scanf("%d",&n) != EOF){        if(n == 0)break;        light.input();        double r;        Point o;        Node nodes[MAXN];        for(int i = 0; i < n; ++i){            o.input();            scanf("%lf",&r);            Point res1,res2;            GetcutPoint(o,r,res1,res2);            //res1.output();            //res2.output();            double a,b,c,x1,x2;            getline(light,res1,a,b,c);            x1 = (-c)/a;            getline(light,res2,a,b,c);            x2 = (-c)/a;            nodes[i].lx = min(x1,x2);            nodes[i].rx = max(x1,x2);        }        sort(nodes,nodes+n,cmp);        double leftx = nodes[0].lx;        double rightx = nodes[0].rx;       printf("%.2lf",nodes[0].lx);        double prevy=nodes[0].rx;        for(int i=1;i<n;i++) {            if(nodes[i].lx>prevy) {                printf(" %.2lf\n%.2lf",prevy,nodes[i].lx);            }            if(prevy<nodes[i].rx) prevy=nodes[i].rx;        }        printf(" %.2lf\n",prevy);        putchar('\n');    }    return 0;}/*poj 1329*///求三角形的外接圆,裸的三角形外接圆,比较水,只要控制输出就行了#include <cstdio>#include <cstring>#include <cmath>using namespace std;#define sqr(a) ( (a*a) )#define EPS 1e-6struct Point{    double x,y;    Point(){}    Point(double _x,double _y):x(_x),y(_y){}    bool input(){        if(scanf("%lf%lf",&x,&y)!= EOF)return 1;        return 0;    }};inline double difcross(Point a,Point b,Point c){    return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);}inline double pdis(Point a,Point b){    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}inline double trarea(Point a,Point b,Point c){    return   fabs(difcross(a,b,c))/2.0;}inline Point get_out_circle(Point a,Point b,Point c){    double c1,c2,xa,xb,xc,ya,yb,yc;    Point o;    xa = a.x,xb = b.x,xc = c.x;    ya = a.y,yb = b.y,yc = c.y;    c1 = (sqr(xa)+sqr(ya)-sqr(xb)-sqr(yb))/2.0;    c2 = (sqr(xa)+sqr(ya)-sqr(xc)-sqr(yc))/2.0;    o.x = (c1*(ya-yc)-c2*(ya-yb))/((xa-xb)*(ya-yc)-(xa-xc)*(ya-yb));    o.y = (c1*(xa-xc)-c2*(xa-xb))/((ya-yb)*(xa-xc)-(ya-yc)*(xa-xb));    return o;}inline double get_out_r(Point a,Point b,Point c){    double ab = pdis(a,b),bc = pdis(b,c),ca = pdis(c,a),s = trarea(a,b,c);    return ab*bc*ca/(4*s);}int main(){    Point a,b,c;    while(a.input()){        b.input();        c.input();        Point o = get_out_circle(a,b,c);        double r = get_out_r(a,b,c);        bool flagx,flagy;        if(o.x > EPS)flagx = 1;        else flagx = 0;        if(o.y > EPS)flagy = 1;        else flagy = 0;        printf("(x ");        if(flagx)printf("- %.3lf)^2 + ",o.x);        else printf("+ %.3lf)^2 + ",-o.x);        printf("(y ");        if(flagy)printf("- %.3lf)^2 ",o.y);        else printf("+ %.3lf)^2 ",-o.y);        printf("= %.3lf^2\n",r);        printf("x^2 + y^2 ");        if(flagx)printf("- %.3lfx ",2*o.x);        else printf("+ %.3lfx ",-2*o.x);        if(flagy)printf("- %.3lfy ",2*o.y);        else printf("+ %.3lfy ",-2*o.y);        double tmp = o.x*o.x+o.y*o.y-r*r;        if(tmp > 0)printf("+ %.3lf = 0\n",tmp);        else printf("- %.3lf = 0\n",-tmp);        puts("");    }    return 0;}/*POJ 2354 Titanic*///求球面上两个点的距离,给的是地理经纬坐标,以前没遇到过这种关于球的问题//由于这个题的输入输出比较烦,所以就换了两个同样的问题,输入输出比较简单一点的,和此题一样/**假设地球是球体,*设地球上某点的经度为lambda,纬度为phi,*则这点的空间坐标是*x=cos(phi)*cos(lambda)*y=cos(phi)*sin(lambda)*z=sin(phi)*设地球上两点的空间坐标分别为(x1,y1,z1),(x2,y2,z2)*直线距离即为R*sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)+(z2-z1)*(z2-z1)),*则它们的夹角为 A = acos(x1 * x2 + y1 * y2 + z1 * z2)*球面距离为 A*R/2(R 即地球半径)*//*poj 2587*/#include<cmath>#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;const int M =1005;const double P=acos(-1.0);struct air{    double lon,lat,j,w;    double x,y,z;}a[M];int n,ans;double minn,maxn;double dist(air a1,air a2){    return (a1.x-a2.x)*(a1.x-a2.x)+(a1.y-a2.y)*(a1.y-a2.y)+(a1.z-a2.z)*(a1.z-a2.z);}int main(){    scanf("%d",&n);    for(int i=0;i<n;i++)    {        scanf("%lf%lf",&a[i].lat,&a[i].lon);        a[i].j=a[i].lon;        a[i].w=a[i].lat;        a[i].lat*=P/180;        a[i].lon*=P/180;        a[i].x=cos(a[i].lat)*cos(a[i].lon);        a[i].y=cos(a[i].lat)*sin(a[i].lon);        a[i].z=sin(a[i].lat);    }    minn=999999.0;    for(int i=0;i<n;i++)    {        maxn=0;        for(int j=0;j<n;j++)        {            double temp=dist(a[i],a[j]);            if(temp>maxn)maxn=temp;        }        if(minn>maxn)        {            minn=maxn;            ans=i;        }    }    printf("%.2lf %.2lf\n",a[ans].w,a[ans].j);    return 0;}/*poj 3407*/#include<cmath>#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;const double P=acos(-1.0);struct node{   double x, y, z;   double lat,lon;};int main(){    double lat1, latm1, lon1, lonm1;    double lat2, latm2, lon2, lonm2;    node p1, p2;    char dir1, dir2;    while(scanf("%lf %lf %c %lf %lf %c",&lat1,&latm1,&dir1,&lon1,&lonm1,&dir2)!=EOF){        p1.lat=(lat1+latm1/60)* P/180;        p1.lon=(lon1 +lonm1/60)*P/180;        if(dir1=='S')p1.lat*=-1.0;        if(dir2=='W')p1.lon*=-1.0;        p1.x=cos(p1.lat)*cos(p1.lon);        p1.y=cos(p1.lat)*sin(p1.lon);        p1.z=sin(p1.lat);        scanf("%lf %lf %c %lf %lf %c",&lat2,&latm2,&dir1,&lon2,&lonm2,&dir2);        p2.lat=(lat2+latm2/60)*P/180;        p2.lon=(lon2+lonm2/60)*P/180;        if(dir1=='S')p2.lat*=-1.0;        if(dir2=='W')p2.lon*=-1.0;        p2.x=cos(p2.lat)*cos(p2.lon);        p2.y=cos(p2.lat)*sin(p2.lon);        p2.z=sin(p2.lat);        double angle=acos(p1.x*p2.x+p1.y*p2.y+p1.z*p2.z);        printf("%.3lf\n",angle*6370.0);    }    return 0;}/*POJ 1106 Transmitters*///这题什么也不用,直接枚举就行了,只用了一个叉积#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>using namespace std;#define EPS 1e-16#define feq(a,b) (fabs((a)-(b))<EPS)//a==b#define fbg(a,b) ((a) > EPS+(b)) //a > b#define fsm(a,b) ((b) > EPS+(a)) //a < b#define fbgeq(a,b) ((a) >= (b)-EPS)  //a >= b#define fsmeq(a,b) ((b) >= (a)-EPS)  //a <= bconst int MAXN = 155;struct Point{    double x,y;    Point(){}    Point(double _x,double _y):x(_x),y(_y){}    bool input(){        if(scanf("%lf%lf",&x,&y)!=EOF)return 1;        return 0;    }};inline double pdis(Point a,Point b){    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}inline double difcross(Point a,Point b,Point c){    return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);}Point points[MAXN];Point o;double r;int main(){    while(o.input()){        scanf("%lf",&r);        if(fsm(r,0))break;        int n;        scanf("%d",&n);        int top = 0;        Point tmp;        while(n --){            tmp.input();            if(fbg(pdis(tmp,o),r))continue;            points[top++] = tmp;        }        int ans = 0,cnt;        for(int i = 0; i < top; ++i){            Point tt = Point(2*o.x-points[i].x,2*o.y-points[i].y);            cnt = 0;            for(int j = 0; j < top; ++j)                if(fsmeq(difcross(points[i],tt,points[j]),0))cnt++;            if(ans < cnt)ans = cnt;        }        printf("%d\n",ans);    }    return 0;}/*http://www.codeforces.com/contest/32/problem/E*///补充一个线段求交的题,要考虑各种情况,特别是共线的时候对两种不同的线段采取不同的策略。#include <cstdio>#include <cstring>#include <cmath>using namespace std;#define EPS 1e-8#define max(a,b) ((a)>(b) ? (a) : (b))#define min(a,b) ((a)<(b) ? (a) : (b))#define feq(a,b) (fabs((a)-(b))<EPS)//a==b#define fbg(a,b) ((a) > EPS+(b)) //a > b#define fsm(a,b) ((b) > EPS+(a)) //a < b#define fbgeq(a,b) ((a) >= (b)-EPS)  //a >= b#define fsmeq(a,b) ((b) >= (a)-EPS)  //a <= b#define sqr(a) ((a)*(a))struct Point{    double x,y;    Point(){}    Point(double _x,double _y):x(_x),y(_y){}    void input(){        scanf("%lf%lf",&x,&y);    }};struct Segment{    Point a,b;    Segment(){}    Segment(Point _a,Point _b):a(_a),b(_b){}};struct Line{    double a,b,c;};Point p1,p2,rp2;Segment wall,mirr;inline double dotcross(Point a,Point b,Point c){    return (b.x-a.x)*(c.x-a.x)+(b.y-a.y)*(c.y-a.y);}inline double sqrpdis(Point a,Point b){    return (a.x - b.x)*(a.x - b.x)+(a.y - b.y)*(a.y - b.y);}inline double difcross(Point a,Point b,Point c){    return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);}inline Point Perpendicular(Point p, Segment s){    Point tp;    double r = dotcross( s.a,p, s.b)/sqrpdis(s.a,s.b);    tp.x=s.a.x+r*(s.b.x-s.a.x);    tp.y=s.a.y+r*(s.b.y-s.a.y);    return Point(2*tp.x-p.x,2*tp.y-p.y);}inline bool SegIntersect(Segment s1,Segment s2){    double mxs1x = max(s1.a.x,s1.b.x), mns1x = min(s1.a.x,s1.b.x);    double mxs2x = max(s2.a.x,s2.b.x), mns2x = min(s2.a.x,s2.b.x);    double mxs1y = max(s1.a.y,s1.b.y), mns1y = min(s1.a.y,s1.b.y);    double mxs2y = max(s2.a.y,s2.b.y), mns2y = min(s2.a.y,s2.b.y);    return fsmeq(difcross(s1.a,s1.b,s2.a)*difcross(s1.a,s1.b,s2.b), 0)&&           fsmeq(difcross(s2.a,s2.b,s1.a)*difcross(s2.a,s2.b,s1.b), 0)&&           fbgeq(mxs1x, mns2x)&&fbgeq(mxs2x, mns1x) &&           fbgeq(mxs1y, mns2y)&&fbgeq(mxs2y, mns1y);}inline bool check(){    Segment s = Segment(p1,p2);    if(!SegIntersect(s,wall)){        if(!SegIntersect(s,mirr)||        (feq(difcross(mirr.a,p1,p2),0)&&feq(difcross(mirr.b,p1,p2),0)))        return 1;    }    return 0;}inline void getline(Point x,Point y,Line &l){    l.a = y.y - x.y;    l.b = x.x - y.x;    l.c = y.x * x.y - x.x * y.y;}bool line_intersect(Line l1,Line l2,Point &p){    double d=l1.a*l2.b-l2.a*l1.b;    if (feq(d, 0)) return 0;    p.x = (l2.c*l1.b-l1.c*l2.b)/d;    p.y = (l2.a*l1.c-l1.a*l2.c)/d;    return true;}inline bool check2(){    if( fsm(difcross(mirr.a, mirr.b, p1)*difcross(mirr.a, mirr.b, p2), 0) )return 0;    Point p3;Line l1,l2;    getline(mirr.a,mirr.b,l2);    double a1 = l2.a,b1 = l2.b,c1 = l2.c;    p3.x = ((sqr(b1) - sqr(a1)) * p2.x - 2 * a1 * b1 * p2.y - 2 * a1 * c1) / (sqr(a1) + sqr(b1));    p3.y = ((sqr(a1) - sqr(b1)) * p2.y - 2 * a1 * b1 * p2.x - 2 * b1 * c1) / (sqr(a1) + sqr(b1));    rp2 = p3;    Segment s = Segment(p1,rp2);    Segment s1 = Segment(p2,rp2);    Point tt;    getline(p1,rp2,l1);    line_intersect(l1,l2,tt);    if (! (tt.x >= min(mirr.a.x, mirr.b.x) &&    tt.x <= max(mirr.a.x, mirr.b.x) &&    tt.y >= min(mirr.a.y, mirr.b.y) && tt.y <= max(mirr.a.y, mirr.b.y)))            return 0;    s1 = Segment(p2,tt);    if(SegIntersect(s1,wall))return 0;    s1 = Segment(p1,tt);    if(SegIntersect(s1,wall))return 0;    return 1;}int main(){    p1.input();    p2.input();    wall.a.input();    wall.b.input();    mirr.a.input();    mirr.b.input();    if(check()){        printf("YES\n");        return 0;    }    if(check2())        printf("YES\n");    else printf("NO\n");}/*POJ 1673 EXOCENTER OF A TRIANGLE*///求三角形垂心,输出时要加eps,不然wa#include <cstdio>#include <cstring>#include <cmath>using namespace std;#define EPS 1e-8struct Point{    double x,y;    Point(){}    Point(double _x,double _y):x(_x),y(_y){}    void input(){        scanf("%lf%lf",&x,&y);    }};struct Line{    double a,b,c;    Line(){}    Line(double _a,double _b,double _c):a(_a),b(_b),c(_c){}};inline bool line_intersect(Line l1,Line l2,Point &p){    double d=l1.a*l2.b-l2.a*l1.b;    if (fabs(d) <= EPS) return 0;    p.x = (l2.c*l1.b-l1.c*l2.b)/d;    p.y = (l2.a*l1.c-l1.a*l2.c)/d;    return true;}inline double difcross(Point p0,Point p1,Point p2){    return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);}inline double pdis(Point a,Point b){    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}inline void getline(Point a,Point b,Point c,Line &l){    l.a = c.x - b.x;    l.b = c.y - b.y;    l.c = (b.y-c.y)*a.y-(c.x-b.x)*a.x;    if(l.a < -EPS){        l.a = -l.a;        l.b = -l.b;        l.c = -l.c;    }}inline double trarea(Point a,Point b,Point c){    return   fabs(difcross(a,b,c))/2.0;}inline Point GetChuiXin(Point a,Point b,Point c){    Line l1,l2;    getline(a,b,c,l1);    getline(c,a,b,l2);    Point ans;    line_intersect(l1,l2,ans);    return ans;}int main(){    Point a,b,c,o;    int cas;    scanf("%d",&cas);    while(cas --){        a.input();        b.input();        c.input();        o = GetChuiXin(a,b,c);        printf("%.4lf %.4lf\n",o.x+EPS,o.y+EPS);    }    return 0;}八、旋转卡壳要理解旋转卡壳到底是个什么东西,最经典的问题就是求凸包的最近距离/*POJ 2187 Beauty Contest*///该题数据比较水,直接求凸包然后枚举也能过,但有些题就必须用卡壳了,比如说://http://acm.tju.edu.cn/toj/showp2847.html这一题考的就是卡壳,不用卡壳是一定超时的。///由于这个东西相对比较难,单独拉到下一篇文章(下一篇文章,旋转卡壳卡卡~)里九。其他问题/*POJ 1981 Circle and Points*///问单位圆最多覆盖几个点。枚举,取任意两点求出圆心,然后查询圆内有多少个点,取最大值即可#include<cmath>#include<cstdio>#include<cstring>using namespace std;#define eps 1e-6struct node{    double x,y;}p[305],center;int n,ans,maxn;inline double dist(node a,node b){    return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);}inline void cer(node p1,node p2){    node p3,mid;    double r1,r2,angle;    p3.x=p1.x-p2.x;    p3.y=p1.y-p2.y;    mid.x=(p1.x+p2.x)/2;    mid.y=(p1.y+p2.y)/2;    r1=dist(p1,mid);    r2=sqrt(1-r1);    angle=atan(-p3.x/p3.y);    center.x=mid.x+r2*cos(angle);    center.y=mid.y+r2*sin(angle);}int main(){    while(scanf("%d",&n),n)    {        for(int i=0;i<n;i++)           scanf("%lf%lf",&p[i].x,&p[i].y);        maxn=1;        for(int i=0;i<n;i++)           for(int j=i+1;j<n;j++)           {               if(dist(p[i],p[j])>4)continue;               ans=0;               cer(p[i],p[j]);               for(int k=0;k<n;k++)               {                    double temp=dist(p[k],center);                    if(temp<=1+eps)ans++;               }               if(ans>maxn)maxn=ans;           }           printf("%d\n",maxn);    }    return 0;}至此,计算几何题目推荐的第一部分完结,赞美神,赞美主 


原创粉丝点击