#include<iostream>
#include<stdlib.h>#include<cmath>using namespace std;#define xmin -1000#define xmax 1000#define ymin -1000#define ymax 1000struct pointnode{ int x; int y;};struct chainnode{ struct pointnode point; struct chainnode *leftnode; struct chainnode *rightnode;};class doublelist{ public: doublelist(int initiationsize=5); ~doublelist(); void insertnode(int index,struct pointnode); void printlist(); void erasenode(int index); void erasenode(chainnode* x); void printreverse(); int size(){return listsize;} int issameline(); struct chainnode* get(int index); pointnode makepointx(pointnode x1,pointnode x2,pointnode x3); pointnode findonepoint(int index); void sortlist(); void convexclosure(); int is_ins(pointnode z); private: chainnode* firstnode; int listsize; };int obtuseangle(pointnode x,pointnode rx,pointnode rrx);double distance(pointnode z,pointnode x);double polar(pointnode z,pointnode x);void doublelist::convexclosure(){ if(listsize<3)return; sortlist(); cout<<endl<<"after sort:"<<endl; printlist(); pointnode yminnode=findonepoint(4); chainnode *p=firstnode,*x,*rx,*rrx; for(int i=0;i<listsize;i++) { if((p->point.x==yminnode.x)&&(p->point.y==yminnode.y)) break; p=p->rightnode; } cout<<"the point min y is:"<<p->point.x<<","<<p->point.y<<endl; int firstflag=0; x=p; rx=x->rightnode; for(;(p!=rx)||(!firstflag);) { rrx=rx->rightnode; if(obtuseangle(x->point,rx->point,rrx->point)) { x=rx;rx=rx->rightnode; firstflag++; } else { erasenode(x);//erase x next node; rx=x; x=x->leftnode; } } }int main(void){ doublelist one; int n; cin>>n; struct pointnode z; for(int i=0;i<n;i++) { cin>>z.x>>z.y; one.insertnode(i,z); }// one.printreverse(); one.convexclosure(); one.printlist(); return 0;}/*131 03 35 44 54 72 61 5-1 7-2 4-3 3-4 2-3 0-1 313 -1 3-1 7-2 4 4 5 1 0 3 35 4-3 3-3 0-4 24 71 52 6*/doublelist::doublelist(int initiationsize){ firstnode=NULL; listsize=0;}doublelist::~doublelist(){ for(int i=0;i<listsize;i++) { struct chainnode* tempnode=firstnode->rightnode; delete firstnode;; firstnode=tempnode; }}void doublelist::printlist(){ struct chainnode *tempnode=firstnode; cout<<"this chain has node:"<<listsize<<endl; for(int i=0;i<listsize;i++) { cout<<tempnode->point.x<<" "<<tempnode->point.y<<endl; tempnode=tempnode->rightnode; } cout<<endl;}void doublelist::erasenode(int index){ struct chainnode* tempnode=firstnode,*deletenode;
for(int i=0;i<index-1;i++) tempnode=tempnode->rightnode; deletenode=tempnode->rightnode; tempnode->rightnode=tempnode->rightnode->rightnode; tempnode->rightnode->leftnode=tempnode; listsize--;}void doublelist::erasenode(chainnode* x){ struct chainnode *tempnode=x; if(x->rightnode==firstnode) firstnode=x->rightnode->rightnode; tempnode->rightnode=tempnode->rightnode->rightnode; tempnode->rightnode->leftnode=tempnode; listsize--;}void doublelist::printreverse(){ cout<<"print reverse list is:"<<endl; struct chainnode *tempnode=firstnode->leftnode; tempnode=tempnode->leftnode; struct chainnode *endnode=tempnode; while(tempnode->leftnode!=endnode) { cout<<tempnode->point.x<<" "<<tempnode->point.y<<endl; tempnode=tempnode->leftnode; } cout<<tempnode->point.x<<" "<<tempnode->point.y<<endl; cout<<endl;}void doublelist::insertnode(int index,struct pointnode z){ if(listsize==0) { struct chainnode *tempnode=new struct chainnode; tempnode->point=z; tempnode->rightnode=tempnode; tempnode->leftnode=tempnode; firstnode=tempnode; } else { if(index==0)
{ struct chainnode *tempnode=new struct chainnode; tempnode->point=z; tempnode->rightnode=firstnode; tempnode->leftnode=firstnode->leftnode; firstnode->leftnode=tempnode; firstnode=tempnode; } else { struct chainnode* tempnode=firstnode; for(int i=0;i<index-1;i++) tempnode=tempnode->rightnode; tempnode->rightnode=new chainnode{z,tempnode,tempnode->rightnode}; tempnode->rightnode->rightnode->leftnode=tempnode->rightnode; }} listsize++;}int doublelist::issameline(){ if(listsize<3)return -1; chainnode *tempnode=firstnode; pointnode x,rx,rrx; for(int i=0;i<(listsize-2);i++) { x=tempnode->point; rx=tempnode->rightnode->point; rrx=tempnode->rightnode->rightnode->point; if(((rx.y-x.y)*1.0/(rx.x-x.x))!=((rx.y-rrx.y)*1.0/(rx.x-rrx.x))) return 0; tempnode=tempnode->rightnode; } return 1;}struct chainnode* doublelist::get(int index){ int i=0; chainnode *tempnode=firstnode; if(index==0) return tempnode; else { while((i++<(index-1))&&(tempnode->rightnode!=NULL)) tempnode=tempnode->rightnode; return tempnode->rightnode; } }pointnode doublelist::makepointx(pointnode x1,pointnode x2,pointnode x3){ int x4,y4,y41,y42,flag=0; pointnode z=x1; while((!flag)||(is_ins(z)))//直到找到一点合适z { x4=rand()%(x3.x-x1.x-1)+x1.x+1; if(x3.x>x2.x) { if(x4<=x2.x) y41=(int)(((x2.y-x1.y)*x4+(x1.y*x2.x-x2.y*x1.x))/(x2.x-x1.x)); else y41=(int)(((x3.y-x2.y)*x4+(x2.y*x3.x-x3.y*x2.x))/(x3.x-x2.x)); y42=(int)(((x3.y-x1.y)*x4+(x1.y*x3.x-x3.y*x1.x))/(x3.x-x1.x)); } else if(x3.x<x2.x) { y41=(int)(((x2.y-x1.y)*x4+(x1.y*x2.x-x2.y*x1.x))/(x2.x-x1.x)); if(x4>x3.x) y42=(int)(((x3.y-x2.y)*x4+(x2.y*x3.x-x3.y*x2.x))/(x3.x-x2.x)); else y42=(int)(((x3.y-x1.y)*x4+(x1.y*x3.x-x3.y*x1.x))/(x3.x-x1.x)); } else { y41=(int)(((x2.y-x1.y)*x4+(x1.y*x2.x-x2.y*x1.x))/(x2.x-x1.x)); y42=(int)(((x3.y-x1.y)*x4+(x1.y*x3.x-x3.y*x1.x))/(x3.x-x1.x)); } if(y41<=(y42+1))continue; else y4=rand()%(y41-y42-1)+y42+1; if((y4<=y42)||(y4>=y41)) flag=0; else flag=1; z.x=x4; z.y=y4; } return z;}
int obtuseangle(pointnode x,pointnode rx,pointnode rrx){//greater than 180 return 1; struct pointnode vectorquantity1,vectorquantity2; vectorquantity1.x=-(x.y-rx.y); vectorquantity1.y=x.x-rx.x;