Graham算法的实现

来源:互联网 发布:国际版的中国软件 编辑:程序博客网 时间:2024/06/13 15:27

算法思路源自于《算法导论》的计算几何章节,并用此算法解决zoj 1453

#include<iostream>#include<vector>#include<algorithm>#include<math.h>#include<fstream>#include<stack>using namespace std;int infinite = 1000;point s;double cross_mul_1(point p0,point p1,point pi){    return (p1.x-p0.x)*(pi.y - p1.y) - (p1.y-p0.y)*(pi.x - p1.x);}bool cmp(const point& p1,const point& p2){    double co1 = (p1.x - s.x) / pow((pow(p1.x - s.x,2.0)+pow(p1.y - s.y,2.0)),0.5) ;    double co2 = (p2.x - s.x) / pow((pow(p2.x - s.x,2.0)+pow(p2.y - s.y,2.0)),0.5) ;    if(co1>co2)        return true;    else if(co1 == co2){        double d1 = pow(p1.x - s.x,2.0)+pow(p1.y-s.y,2.0);        double d2 = pow(p2.x - s.x,2.0)+pow(p2.y-s.y,2.0);        //在次将同一直线上的最远的点放在更前面,为了后面编程方便        return d1 > d2;                                         }    return false;}void graham(){    ifstream cin("1.txt");    int n,i,x,y;    cin>>n;    vector<point> v;    double minY = infinite ,minX = infinite ,tx,ty;    for( i=0;i<n;++i){        point p;        cin>>x>>y;        if(y < minY){            ty = minY;            minY = y;            y = ty;            tx = minX;            minX = x;            x = tx;        }        else if(y == minY && x < minX){            tx = minX;            minX = x;            x = tx;        }        if(i!=0){         //作为原点的点不加入vector中            p.x = x;            p.y = y;             v.push_back(p);         }    }    s.x = minX;    s.y = minY;    sort(v.begin(),v.end(),cmp);        //对夹角进行排序    stack<point> sta;    sta.push(s);    sta.push(v[0]);    sta.push(v[1]);    point p0,p1;    double t;    for(int i = 2;i<v.size();++i){        p1 = sta.top();        sta.pop();                        //这里STL很不好用啊,不能直接访问栈里的元素        p0 = sta.top();        sta.push(p1);        t = cross_mul_1(p0,p1,v[i]);        if(t == 0){            continue;              //跳过在同一直线上较近的点        }        while(t < 0){            sta.pop();            p1 = sta.top();            sta.pop();                                    p0 = sta.top();            sta.push(p1);            t = cross_mul_1(p0,p1,v[i]);        }        sta.push(v[i]);    }    p0 = s;    printf("( %f , %f )\n",s.x,s.y);    double sum = 0;    while(!sta.empty()){        p1 = sta.top();        printf("( %f , %f )\n",p1.x,p1.y);        sum += pow(pow(p1.x - p0.x,2.0)+pow(p1.y-p0.y,2.0),0.5);        p0 = p1;        sta.pop();    }    cout.precision(2);    cout<<fixed<<sum<<endl;}int main(){    graham();}
原创粉丝点击