#include <iostream>
#include <cstdio>
#include <stdlib.h>
#include <cmath>
using namespace std;
const int MAX = 1000;
typedef struct point{
int x, y;
int flag;
}point;
point list[MAX];
int stack[MAX], top;
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) - (p1.y-p0.y)*(p2.x-p0.x);
}
int comp(const void *pp1, const void *pp2){//比较函数
point *p1 = (point*)pp1, *p2 = (point*)pp2;
return CrossProd(list[0], *p1, *p2)*(-1);
}
void graham(int n){//用栈实现
int i;
if(1 == n){
printf("(%d,%d)\n", list[0].x, list[0].y);
}
if(2 == n){
printf("(%d,%d)(%d,%d)\n", list[0].x, list[0].y, list[1].x, list[1].y);
}
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--;
}
stack[++top] = i;
}
for(i = 0; i <= top; i++){
printf("(%d,%d)\n", list[stack[i]].x, list[stack[i]].y);
}
}
}
void select(int n, int &num){//去掉角度相同的不部分点
point p1, p2;
int t, i, j;
for(int i = 1; i <= n-2; i++){
p1 = list[i];
if(p1.flag){
for(j = i + 1; j <= n-1; j++ ){
p2 = list[j];
if(p2.flag){
t = CrossProd(list[0], p1, p2);
if(0 == t){
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(1 == list[j].flag){
list[i++] = list[j];
}
}
num = i - 1;//去掉list[0]余下的顶点数目
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;//多边形的总点数
}
int main()
{
int count = 0, n, num;
while(cin>>n){
if(0 == n){
break;
}
cout << "set" << ++count << ":\n";
num = init(n);
graham(num);
}
return 0;
}
/*************
测试数据
13
0 0
70 -50
60 30
-30 -50
80 10
50 -10
0 -30
80 20
50 -60
90 -20
-30 -40
-10 -60
90 10
**********/
求凸包(Graham-Scan)
最新推荐文章于 2023-03-18 15:42:47 发布