#include <iostream> #include <fstream> #include <string> #include <sstream> using namespace std; struct Point { int x,y; friend std::ostream &operator << (std::ostream &output,const Point &p); friend std::istream &operator >> (std::istream &input,Point &p); }; bool operator == (Point a,Point b) { return (a.x == b.x && a.y == b.y); } std::ostream &operator << (std::ostream &output,const Point &p) { output<<"( "<<p.x<<" , "<<p.y<<" ) "; return output; } std::istream &operator >> (std::istream &input,Point &p) { input>>p.x>>p.y;; return input; } template<class T> class Link { private: T data; Link<T> *next; Link<T> *previous; public: Link(T data); void displayLink(); T getData(); void setData(T data); Link<T> *getNext(); void setNext(Link<T> *next); Link<T> *getPrevious(); void setPrevious(Link<T> *previous); template<class U> friend std::ostream& operator<< (std::ostream& print, Link<U>& obj); }; template<class T> Link<T>::Link(T data) { setData(data); setNext(NULL); setPrevious(NULL); } template<class T> void Link<T>::displayLink() { std::cout<<getData()<<" "; } template<class T> T Link<T>::getData() { return data; } template<class T> void Link<T>::setData(T data) { this->data = data; } template<class T> Link<T> *Link<T>::getNext() { return next; } template<class T> void Link<T>::setNext(Link<T> *next) { this->next = next; } template<class T> Link<T> *Link<T>::getPrevious() { return previous; } template<class T> void Link<T>::setPrevious(Link<T> *previous) { this->previous = previous; } template <class U> std::ostream& operator<<(std::ostream& print, Link<U> & L) { print << L.getData(); return print; } template<class T> class DoublyLinkedList { private: Link<T> *first; Link<T> *last; public: DoublyLinkedList(); ~DoublyLinkedList(); Link<T> *getFirst(); Link<T> *getFirst() const; void setFirst(Link<T> *first); Link<T> *getLast(); void setLast(Link<T> *first); bool isEmpty(); Link<T> *find(T key); void insertFirst(T dd); void insertLast(T dd); void deleteFirst(); void deleteLast(); bool insertAfter(T key,T dd); void deleteKey(T key); void displayForward(); void displayBackward(); }; template<class T> DoublyLinkedList<T>::DoublyLinkedList() { setFirst(NULL); setLast(NULL); } template<class T> DoublyLinkedList<T>::~DoublyLinkedList() { while(!isEmpty()) { deleteFirst(); } } template<class T> Link<T> *DoublyLinkedList<T>::getFirst() { return first; } template<class T> Link<T> *DoublyLinkedList<T>::getFirst() const { return first; } template<class T> void DoublyLinkedList<T>::setFirst(Link<T> *first) { this->first = first; } template<class T> Link<T> *DoublyLinkedList<T>::getLast() { return last; } template<class T> void DoublyLinkedList<T>::setLast(Link<T> *last) { this->last = last; } template<class T> bool DoublyLinkedList<T>::isEmpty() { return getFirst()==NULL; } template<class T> Link<T> *DoublyLinkedList<T>::find(T key) { Link<T> *current = getFirst(); while(current != NULL && !(current->getData == key)) current = current->getNext(); return current; } template<class T> void DoublyLinkedList<T>::insertFirst(T dd) { Link<T> *newLink = new Link<T>(dd); if(isEmpty()) setLast(newLink); else getFirst()->setPrevious(newLink); newLink->setNext(getFirst()); setFirst(newLink); } template<class T> void DoublyLinkedList<T>::insertLast(T dd) { Link<T> *newLink = new Link<T>(dd); if(isEmpty()) { setFirst(newLink); } else { getLast()->setNext(newLink); newLink->setPrevious(getLast()); } setLast(newLink); } template<class T> void DoublyLinkedList<T>::deleteFirst() { if(isEmpty()) return; Link<T> *temp = getFirst(); if(getFirst()->getNext() == NULL) setLast(NULL); else getFirst()->getNext()->setPrevious(NULL); setFirst(getFirst()->getNext()); delete temp; } template<class T> void DoublyLinkedList<T>::deleteLast() { if(isEmpty()) return; Link<T> *temp = getLast(); if(getFirst()->getNext() == NULL) setFirst(NULL); else getLast()->getPrevious()->setNext(NULL); setLast(getLast()->getPrevious()); delete temp; } template<class T> bool DoublyLinkedList<T>::insertAfter(T key,T dd) { Link<T> *current = find(key); if(current == NULL) return false; Link<T> *newLink = new Link<T>(dd); if(current->getNext() == NULL) { newLink->setNext(NULL); setLast(newLink); } else { newLink->setNext(current->getNext()); current->getNext()->setPrevious(newLink); } newLink->setPrevious(current); current->setNext(newLink); return true; } template<class T> void DoublyLinkedList<T>::deleteKey(T key) { Link<T> *current = find(key); if(current==NULL) return; if(current->getPrevious() == NULL) setFirst(current->getNext()); else current->getPrevious()->setNext(current->getNext()); if(current->getNext() == NULL) setLast(current->getPrevious()); else current->getNext()->setPrevious(current->getPrevious()); delete current; } template<class T> void DoublyLinkedList<T>::displayForward() { std::cout<<"List (first-->last): "; Link<T> *current = getFirst(); while(current != NULL) { current->displayLink(); current = current->getNext(); } std::cout<<"\n"; } template<class T> void DoublyLinkedList<T>::displayBackward() { std::cout<<"List (last-->first): "; Link<T> *current = getLast(); while(current != NULL) { current->displayLink(); current = current->getPrevious(); } std::cout<<"\n"; } int ScaledDistance(Point u,Point v,Point p) { return (p.x - v.x) * (u.y - v.y) - (p.y - v.y) * (u.x - v.x); } int Direction(Point u,Point v, Point p) { return (p.x - v.x) * (u.y - v.y) - (p.y - v.y) * (u.x - v.x); } int Projection(Point u,Point v,Point p) { return (p.x - v.x) * (u.x - v.x) + (p.y - v.y) *(u.y - v.y); } void Select(Point &p,Point &q, const DoublyLinkedList<Point>& S) { Point pt; Link<Point> *element = S.getFirst(); q = element->getData(); p = q; element = element->getNext(); while(element != NULL) { pt = element->getData(); if((pt.y < q.y) || (pt.y == q.y && pt.x < q.x)) q = pt; if((pt.y > p.y) || (pt.y == p.y && pt.x > p.x)) p = pt; element = element->getNext(); } } void Split(Point p, Point q, DoublyLinkedList<Point> &S, DoublyLinkedList<Point> &R, DoublyLinkedList<Point> &L) { int dir; Point pt; while(!S.isEmpty()) { pt = S.getFirst()->getData(); S.deleteFirst(); dir = Direction(p,q,pt); if(dir > 0) R.insertLast(pt); if(dir < 0) L.insertLast(pt); } } void PruneAndSplit(Point p, Point q,Point r, DoublyLinkedList<Point> &S, DoublyLinkedList<Point> &U, DoublyLinkedList<Point> &L) { DoublyLinkedList<Point> internal1,internal2; Split(p,r,S,U,internal1); Split(r,q,internal1,L,internal2); while(!internal2.isEmpty()) internal2.deleteFirst(); } Point FarthestPoint(Point p,Point q,DoublyLinkedList<Point> &S) { int maxdist,dist; Point r,pt; maxdist = 0; Link<Point> *element = S.getFirst(); while(element != NULL) { pt = element->getData(); dist = ScaledDistance(p,q,pt); if(dist > maxdist) { maxdist = dist; r = pt; } else if(dist == maxdist) { if(Projection(p,q,pt) > Projection(p,q,r)) { maxdist = dist; r = pt; } } element = element->getNext(); } return r; } void QuickHull(Point p,Point q,DoublyLinkedList<Point> &S,DoublyLinkedList<Point> &CH) { Point r; DoublyLinkedList<Point> U,L; if(!S.isEmpty()) { r = FarthestPoint(p,q,S); PruneAndSplit(p,q,r,S,U,L); QuickHull(p,r,U,CH); CH.insertLast(r); QuickHull(r,q,L,CH); } } void Solve(DoublyLinkedList<Point> &A,DoublyLinkedList<Point> &CH) { DoublyLinkedList<Point> S,L,R; Point p,q; Link<Point> *element = A.getFirst(); while(element != NULL) { S.insertLast(element->getData()); element = element->getNext(); } Select(p,q,S); Split(p,q,S,R,L); CH.insertLast(p); QuickHull(p,q,R,CH); CH.insertLast(q); QuickHull(q,p,L,CH); } int main(int argc, char *argv[]) { DoublyLinkedList<Point> A; DoublyLinkedList<Point> B; stringstream ss; Point p; string line; int counter; while(getline(cin,line)) { ss.clear(); ss.str(line); counter = 1; while(ss) { try { switch(counter) { case 1: { ss>>p.x; break; } case 0: { ss>>p.y; A.insertLast(p); break; } } } catch(...) { } counter = (counter + 1)%2; } Solve(A,B); cout<<"List A \n"; A.displayForward(); A.displayBackward(); cout<<"List B \n"; B.displayForward(); B.displayBackward(); while(!A.isEmpty()) A.deleteFirst(); while(!B.isEmpty()) B.deleteFirst(); } return EXIT_SUCCESS; }
573 40 686 88 733 276 641 169 695 368 656 274 625 355 592 274 563 259 540 409 494 491 517 359 532 173 405 403 379 455 464 217 538 95 256 488 349 351 406 259 259 390 333 307 183 434 331 243 164 374 235 316 54 460 279 247 313 204 65 342 118 306 220 242 165 244 330 146 17 264 91 234 225 149 153 171 447 73 76 159 280 94 174 71 1 1 4 3 2 0 2 2 4 1 3 2 3 4 1 3 2 3 187 141 247 331 91 315 324 187 80 166 337 308 210 437 284 270 370 377 413 217 195 332 418 458 292 324 217 186
List A List (first-->last): ( 573 , 40 ) ( 686 , 88 ) ( 733 , 276 ) ( 641 , 169 ) ( 695 , 368 ) ( 656 , 274 ) ( 625 , 355 ) ( 592 , 274 ) ( 563 , 259 ) ( 540 , 409 ) ( 494 , 491 ) ( 517 , 359 ) ( 532 , 173 ) ( 405 , 403 ) ( 379 , 455 ) ( 464 , 217 ) ( 538 , 95 ) ( 256 , 488 ) ( 349 , 351 ) ( 406 , 259 ) ( 259 , 390 ) ( 333 , 307 ) ( 183 , 434 ) ( 331 , 243 ) ( 164 , 374 ) ( 235 , 316 ) ( 54 , 460 ) ( 279 , 247 ) ( 313 , 204 ) ( 65 , 342 ) ( 118 , 306 ) ( 220 , 242 ) ( 165 , 244 ) ( 330 , 146 ) ( 17 , 264 ) ( 91 , 234 ) ( 225 , 149 ) ( 153 , 171 ) ( 447 , 73 ) ( 76 , 159 ) ( 280 , 94 ) ( 174 , 71 ) List (last-->first): ( 174 , 71 ) ( 280 , 94 ) ( 76 , 159 ) ( 447 , 73 ) ( 153 , 171 ) ( 225 , 149 ) ( 91 , 234 ) ( 17 , 264 ) ( 330 , 146 ) ( 165 , 244 ) ( 220 , 242 ) ( 118 , 306 ) ( 65 , 342 ) ( 313 , 204 ) ( 279 , 247 ) ( 54 , 460 ) ( 235 , 316 ) ( 164 , 374 ) ( 331 , 243 ) ( 183 , 434 ) ( 333 , 307 ) ( 259 , 390 ) ( 406 , 259 ) ( 349 , 351 ) ( 256 , 488 ) ( 538 , 95 ) ( 464 , 217 ) ( 379 , 455 ) ( 405 , 403 ) ( 532 , 173 ) ( 517 , 359 ) ( 494 , 491 ) ( 540 , 409 ) ( 563 , 259 ) ( 592 , 274 ) ( 625 , 355 ) ( 656 , 274 ) ( 695 , 368 ) ( 641 , 169 ) ( 733 , 276 ) ( 686 , 88 ) ( 573 , 40 ) List B List (first-->last): ( 494 , 491 ) ( 695 , 368 ) ( 733 , 276 ) ( 686 , 88 ) ( 573 , 40 ) ( 174 , 71 ) ( 76 , 159 ) ( 17 , 264 ) ( 54 , 460 ) ( 256 , 488 ) List (last-->first): ( 256 , 488 ) ( 54 , 460 ) ( 17 , 264 ) ( 76 , 159 ) ( 174 , 71 ) ( 573 , 40 ) ( 686 , 88 ) ( 733 , 276 ) ( 695 , 368 ) ( 494 , 491 ) List A List (first-->last): ( 1 , 1 ) ( 4 , 3 ) ( 2 , 0 ) ( 2 , 2 ) ( 4 , 1 ) ( 3 , 2 ) ( 3 , 4 ) ( 1 , 3 ) ( 2 , 3 ) List (last-->first): ( 2 , 3 ) ( 1 , 3 ) ( 3 , 4 ) ( 3 , 2 ) ( 4 , 1 ) ( 2 , 2 ) ( 2 , 0 ) ( 4 , 3 ) ( 1 , 1 ) List B List (first-->last): ( 3 , 4 ) ( 4 , 3 ) ( 4 , 1 ) ( 2 , 0 ) ( 1 , 1 ) ( 1 , 3 ) List (last-->first): ( 1 , 3 ) ( 1 , 1 ) ( 2 , 0 ) ( 4 , 1 ) ( 4 , 3 ) ( 3 , 4 ) List A List (first-->last): ( 187 , 141 ) ( 247 , 331 ) ( 91 , 315 ) ( 324 , 187 ) ( 80 , 166 ) ( 337 , 308 ) ( 210 , 437 ) List (last-->first): ( 210 , 437 ) ( 337 , 308 ) ( 80 , 166 ) ( 324 , 187 ) ( 91 , 315 ) ( 247 , 331 ) ( 187 , 141 ) List B List (first-->last): ( 210 , 437 ) ( 337 , 308 ) ( 324 , 187 ) ( 187 , 141 ) ( 80 , 166 ) ( 91 , 315 ) List (last-->first): ( 91 , 315 ) ( 80 , 166 ) ( 187 , 141 ) ( 324 , 187 ) ( 337 , 308 ) ( 210 , 437 ) List A List (first-->last): ( 284 , 270 ) ( 370 , 377 ) ( 413 , 217 ) ( 195 , 332 ) ( 418 , 458 ) ( 292 , 324 ) ( 217 , 186 ) List (last-->first): ( 217 , 186 ) ( 292 , 324 ) ( 418 , 458 ) ( 195 , 332 ) ( 413 , 217 ) ( 370 , 377 ) ( 284 , 270 ) List B List (first-->last): ( 418 , 458 ) ( 413 , 217 ) ( 217 , 186 ) ( 195 , 332 ) List (last-->first): ( 195 , 332 ) ( 217 , 186 ) ( 413 , 217 ) ( 418 , 458 )