#include <iostream>#include <cmath>using namespace std;struct POINT { int x, y; int flag; // 表示是否在连线内部,在为0};POINT list[500], pk;int stack[500], top, k, rightnum;void swap(POINT &a, POINT &b){ POINT t; t = a; a = b; b = t;}int CrossProd(POINT p0, POINT p1, POINT p2){ return (p1.x - p0.x) * (p2.y - p0.y) - (p2.x - p0.x) * (p1.y - p0.y);}int comp(const void *pp1, const void *pp2){ //int t; POINT *p1 = (POINT*)pp1, *p2 = (POINT*)pp2; return CrossProd(list[0], *p1, *p2)*(-1);}void select(int n, int &num){ POINT p1, p2; int t, i, j, f; for (i = 1; i < n; i++) { f = 0; p1 = list[i]; if (p1.flag) { for (j = i + 1; j < n; j++) { p2 = list[j]; if (p2.flag) { t = CrossProd(list[0], p1, p2); if (t == 0) { if ((p1.x - list[0].x) * (p1.x - list[0].x) + (p1.y - list[0].y) *(p1.y - list[0].y) \ < (p2.x - list[0].x) * (p2.x - list[0].x) + (p2.y - list[0].y) *(p2.y - list[0].y)) { list[i].flag = 0; } else list[j].flag = 0; } } } } } i = 1; for (j = 1; j < n; j++) { if (list[j].flag == 1) { list[i] = list[j]; i++; } } num = i - 1; qsort(list + 1, num, sizeof(POINT), comp);}int init(int n){ int i, num; for (i = 0; i < n; i++) { cin >> list[i].x >> list[i].y; list[i].flag = 1; if ((list[i].y < list[0].y) || (list[i].y == list[0].y) && (list[i].x < list[0].x)) { swap(list[0], list[i]); } } select(n, num); return num + 1;}void graham(int n){ int i; if (n == 1) cout << "(" << list[0].x << ", " << list[0].y << ")" << endl; if (n == 2) cout << "(" << list[0].x << ", " << list[0].y << ")" \ "(" << list[1].x << ", " << list[1].y << ")" << endl; if (n > 2) { for (i = 0; i <= 2; i++) stack[i] = i; top = 2; for (i = 3; i <= n-1; i++) { while (CrossProd(list[stack[top-1]], list[stack[top]], list[i]) <= 0) top--; top++; stack[top] = i; } for (i = 0; i <= top; i++) cout << "(" << list[stack[i]].x << ", " << list[stack[i]].y << ")"; cout << endl; }}void Chain(int n, int LR) // LR=1生成右链,LR=0生成左链{ int m = 0, i, t; POINT pm; stack[0] = 0; top = 0; while (m != k) { pm = pk; m = k; for (i = 1; i < n; i++) { t = CrossProd(list[stack[top]], list[i], pm); if ((t > 0 && LR==1) || (t < 0 && LR == 0) ||\ (t == 0) && ((list[i].x - list[stack[top]].x) * (list[i].x - list[stack[top]].x) \ + (list[i].y - list[stack[top]].y)*(list[i].y - list[stack[top]].y) > (pm.x - list[stack[top]].x) * (pm.x - list[stack[top]].x) \ + (pm.y - list[stack[top]].y) * (pm.y - list[stack[top]].y))) { pm = list[i]; m = i; } } top ++; stack[top] = m; } if (LR == 1) { for (i = 0; i <= top; i++) { cout << "(" <<list[stack[i]].x << ", " << list[stack[i]].y << ")"; } } else { for (i = top - 1; i > 0; i--) { cout << "(" <<list[stack[i]].x << ", " << list[stack[i]].y << ")"; } cout << endl; }}void init2(int n){ int i; for (i = 0; i < n; i++) { cin >> list[i].x >> list[i].y; if (i == 0) { pk = list[0]; k = 0; } if ((list[i].y < list[0].y) || (list[i].y == list[0].y) && (list[i].x < list[0].x)) swap(list[0], list[i]); if ((list[i].y > pk.y) || (list[i].y == pk.y) && (list[i].x > pk.x)) { pk = list[i]; k = i; } }}void Jarvis(int n){ if (n == 1) cout << "(" << list[0].x << ", " << list[0].y << ")" << endl; if (n == 2) cout << "(" << list[0].x << ", " << list[0].y << ")" \ "(" << list[1].x << ", " << list[1].y << ")" << endl; if (n > 2) { Chain(n, 1); Chain(n, 0); }}int main(){ int count = 0, n, num; while (cin >> n) { if (n == 0) break; count++; cout << "set" << count << ":\n"; cout << "graham...(\n)"; num = init(n); graham(num); cout << "Jarvis...(\n)"; init2(n); Jarvis(n); } return 0;}