圈水池
时间限制:
3000
ms
|
内存限制:
65535
KB
难度:
4
-
描述
- 有一个牧场,牧场上有很多个供水装置,现在牧场的主人想要用篱笆把这些供水装置圈起来,以防止不是自己的牲畜来喝水,各个水池都标有各自的坐标,现在要你写一个程序利用最短的篱笆将这些供水装置圈起来!(篱笆足够多,并且长度可变)
-
-
输入
-
第一行输入的是N,代表用N组测试数据(1<=N<=10)
第二行输入的是m,代表本组测试数据共有m个供水装置(3<=m<=100)
接下来m行代表的是各个供水装置的横纵坐标
输出
- 输出各个篱笆经过各个供水装置的坐标点,并且按照x轴坐标值从小到大输出,如果x轴坐标值相同,再安照y轴坐标值从小到大输出 样例输入
-
1 4 0 0 1 1 2 3 3 0
样例输出
-
0 0 2 3 3 0
来源
- [张洁烽]原创
- 代码:
-
#include
#include
#include
using namespace std;
#define MaxNode 101 -
int stack[MaxNode];
int top; -
typedef struct TPoint
{
int x;
int y;
}TPoint; - TPoint point[MaxNode];
-
void swap(TPoint point[], int i, int j)
{
TPoint tmp;
tmp = point[i];
point[i] = point[j];
point[j] = tmp;
} -
double multi(TPoint p1, TPoint p2, TPoint p0)
{
return (p1.x - p0.x) * (p2.y - p0.y) - (p2.x - p0.x) * (p1.y - p0.y);
} -
double distance(TPoint p1, TPoint p2)
{
return (p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y);
} -
int cmp(const void *a, const void *b)
{
TPoint *c = (TPoint *)a;
TPoint *d = (TPoint *)b;
double k = multi(*c, *d, point[0]);
if(k< 0) return 1;
else if(k == 0 && distance(*c, point[0]) >= distance(*d, point[0]))
return 1;
else return -1;
} -
void grahamScan(int n)
{
//Graham扫描求凸包
int i, u;
//将最左下的点调整到p[0]的位置
u = 0;
for(i = 1;i <= n - 1;i++){
if((point[i].y < point[u].y) ||
(point[i].y == point[u].y && point[i].x < point[u].x))
u = i;
}
swap(point, 0, u);
//将平p[1]到p[n - 1]按按极角排序,可采用快速排序
qsort(point + 1, n - 1, sizeof(point[0]), cmp);
for(i = 0;i <= 2;i++) stack[i] = i;
top = 2;
for(i = 3;i <= n - 1;i++){
while(multi(point[i], point[stack[top]], point[stack[top - 1]]) >= 0){
top--;
if(top == 0) break;
}
top++;
stack[top] = i;
}
int j,s;
for(i=0;i<=top;i++)
{
for(j=i+1;j<=top;j++)
{
if(point[stack[i]].x>point[stack[j]].x)
{
s=point[stack[j]].x;
point[stack[j]].x=point[stack[i]].x;
point[stack[i]].x=s;
s=point[stack[j]].y;
point[stack[j]].y=point[stack[i]].y;
point[stack[i]].y=s;
}
else if(point[stack[i]].x==point[stack[j]].x)
{
if(point[stack[i]].y>point[stack[j]].y)
{
s=point[stack[j]].x;
point[stack[j]].x=point[stack[i]].x;
point[stack[i]].x=s;
s=point[stack[j]].y;
point[stack[j]].y=point[stack[i]].y;
point[stack[i]].y=s;
}
}
}
}
for(i=0;i<=top;i++)
{
printf("%d %d\n",point[stack[i]].x,point[stack[i]].y);
}
}
int main()
{
int n;
scanf("%d",&n);
while(n--)
{
int m;
scanf("%d",&m);
for(int i=0;i
{
scanf("%d%d",&point[i].x,&point[i].y);
}
grahamScan(m);
}
return 0;
}
-
第一行输入的是N,代表用N组测试数据(1<=N<=10)