#include <iostream> #include <queue> #include <vector> #include <stack> using namespace std; //点结构体 typedef struct { int x,y; }Point; //左下角点Po Point leftBotm; //极角比较函数 int leftTurn(Point p1,Point p2,Point p3) //p1:next-top, p2:top(), p3:pi { int ret=(p3.x-p1.x)*(p2.y-p1.y)-(p2.x-p1.x)*(p3.y-p1.y); if(ret<0) { return -1; //左转 } else if(ret==0) { return 0; // 共线 } else { return 1; //右转 } } //仿比较函数结构体 struct compare { bool operator()(const Point &p,const Point &q) { int ret=leftTurn(leftBotm,p,q); if(ret==-1) { return false; } else if(ret==1) { return true; } else { int minus=(p.x-leftBotm.x)*(p.x-leftBotm.x)-(q.x-leftBotm.x)*(q.x-leftBotm.x); if(minus<0) { return false; } else { return true; } } } }; //最小堆 typedef priority_queue<Point,vector<Point>,compare> minHeap; int main() { minHeap heap; int n; Point input; vector<Point> final; cin>>n; int x,y,k; cin>>input.x>>input.y; final.push_back(input); x=input.x; y=input.y; k=0; for(int i=1;i<n;++i) { cin>>input.x>>input.y; final.push_back(input); if(input.x<=x&&input.y<=y) { x=input.x; y=input.y; k=i; } } leftBotm.x=x; leftBotm.y=y; for(int i=0;i<n;++i) { if(i!=k) { heap.push(final[i]); } } Point pre,now; pre=heap.top(); heap.pop(); final.clear(); while(!heap.empty()) { now=heap.top(); heap.pop(); if(leftTurn(leftBotm,pre,now)==0) { pre=now; } else { final.push_back(pre); pre=now; } } final.push_back(pre); /* 全部已经按极角整理完毕,重复角只保留距离最远的 */ stack<Point> s; s.push(leftBotm); s.push(final[0]); s.push(final[1]); for(int j=2;j<(int)final.size();++j) { while(leftTurn(s._Get_container()[s.size()-2],s._Get_container()[s.size()-1],final[j])!=-1) { s.pop(); } s.push(final[j]); } cout<<endl; for(int k=0;k<(int)s.size();++k) { cout<<s._Get_container()[k].x<<","<<s._Get_container()[k].y<<endl; } return 0; }