题目:
建设一个围栏,围栏的部分只有横向和竖向两种方向,围栏的拐角处算一个点,给出围栏的所有点,计算出围栏的总长度。
解题思路:
1 围栏由多个线段构成,每个线段的长度至少为1.
2 线段不是横向的就是竖向的
3 x坐标相等或y坐标相等的点数目必定为偶数。
4 按x坐标从小到大排序,x坐标相等按y坐标从小到大排序
5 顺序扫描数组,挨个计算两点之间的距离,即list[1].y-list[0].y ,list[3].y-list[2].y。。,将距离加入总长度
6 交换所有点的x、y坐标,重复步骤4、5
7 输出结果。
代码:
#include<stdio.h>
typedef struct
{
int x;
int y;
} Point;
int cmp(const void *a, const void *b)
{
Point *p1, *p2;
p1 = (Point*)a;
p2 = (Point*)b;
if(p1->x != p2->x)
return p1->x - p2 -> x;
else return p1->y - p2->y;
}
int calculateLen(Point* list, int n)
{
int i,len;
len=0;
i=0;
while(i<n) //计算第1个点到第2个点的距离,第3个点到第4个点的距离,依次类推
{
len += list[i+1].y - list[i].y;
i += 2;
}
return len;
}
int main()
{
int n,n_old; //点的数目
int i,temp;
int len=0; //围栏长度
Point *list; //点的集合
scanf("%d", &n);
n_old=0;
list=NULL;
while(n)
{
len=0;
if(n > n_old)
{
if(list != NULL) free(list);
list = (Point *)malloc(sizeof(Point)*n);
}
//输出n个点
for(i=0; i<n; i++)
{
scanf("%d %d", &list[i].x, &list[i].y);
}
//排序
qsort(list, n, sizeof(Point), cmp) ;
//计算竖向的围栏长度
len += calculateLen(list, n);
//交换x、y坐标
for(i=0; i<n; i++)
{
temp=list[i].x;
list[i].x = list[i].y;
list[i].y = temp;
}
//排序
qsort(list, n, sizeof(Point), cmp) ;
//计算横向的围栏长度
len += calculateLen(list, n);
//输出结果
printf("The length of the fence will be %d units.\n", len);
n_old=n;
scanf("%d", &n);
}
return 0;
}