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

很多题,很多代码:

一、点,线,面,形基本关系,点积叉积的理解
/*poj2318toys*/
//判断箱子每一个块内有多少个玩具,可以用叉积的性质找到玩具的位置,过程采用二分查找。
#include <cstdio>
#include <cstring>
using namespace std;
#define EPS 1e-8
const 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-8
inline 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-8
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;
};

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 99999999
const 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 1000000000
const 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-8
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;
};
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 <= 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){}
};

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 <= b
const 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 <= b

const 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 <= b
const 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 <= b
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);
    }
};
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 <= b

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);
    }
};

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 <= b

const 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 <= b
const 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,一律输出NO
2. 所有点共线,NO
3. 凸包上每条边上至少有三点,否则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 <= b
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);
    }
    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-6
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 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 <= b
const 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-8
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){}
};

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-6
struct 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;
}



至此,计算几何题目推荐的第一部分完结,赞美神,赞美主
 


你可能感兴趣的:(计算几何题目推荐第一期AC代码)