问题:在一个按照东西和南北方向划分成规整街区的城市里,n个居民点散乱地分布在不同的街区中。用x坐标表示东西向,用y坐标表示南北向。各居民点的位置可以由坐标(x,y)表示。街区中任意两点(x1,y1)和(x2,y2)之间的距离可以用数值|x1-x2|+|y1-y2|度量。居民们希望在城市中选择建立超市的最佳位置,使n个居民点到超市的距离总和最小。
编程任务:给定n个居民点的位置,编程计算n个居民点到超市的距离总和的最小值。
输入:输入由多组测试数据组成。每组测试数据输入的第1行是居民点数n,接下来n行是居民点的位置,每行两个整数x和y。
输出:对应每组输入,输出数据是n个居民点到超市距离总和的最小值。
输入示例: 5 居民点到超市最小距离和:10
1 2
2 2
1 3
3 -2
3 3
解决方法:超市选址问题的核心可以看成是求中值的问题,即n个居民点的横、纵坐标值的中位数就是最优解。为此可先求出n个居民点的x坐标值和y坐标值的中位数,然后由此求得n个居民点到超市距离总和的最小值。
注意事项:本实验需完成算法设计、数据结构的选择、运行结果分析以及相关内容的说明等。例如,求中位数的过程可用快速排序等算法将n个居民点的x和y坐标分别排序后,计算出中位数。程序的编写可以参考以下步骤:
1、输入居民点位置文件,或用随机数发生器得到各居民点位置坐标(x,y)。
2、将输入的二维数组(x,y)转化为两个一维数组(x)、(y)。
3、计算横坐标和纵坐标数组的中位数。
4、求n个居民点到超市距离总和的最小值,并输出此值,并以图示的方式显示居民点与超市的位置分布。
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
void sort(int *a,int len)
{int i=0;
int j;
int t;
for(i=0;i<len;i++)
{
for(j=0;j<len-i-1;j++)
{
if(a[j]>a[j+1])
{
t=a[j];
a[j]=a[j+1];
a[j+1]=t;
}
}
}
}
int Median(int *x,int n){//返回数组中的中位数
if(n%2==0){
return ((x[n/2-1]+x[n/2])/2);
}
else {
return (x[n/2]);
}
}//Median
int main(){
int n;//居民点个数n
int map[12][12];
int *x;
int *y;
int i=0,j=0;
for(i=0;i<12;i++){//map初始化
for(j=0;j<12;j++){
map[i][j]=0;
}
}//for 0为空,1为坐标原点,2为超市位置,3为居民点,4为原点与超市重合,5为超市与居民区重合,6为居民区与原点重合
map[5][5]=1;//该点为坐标原点
printf("The number of people:\n");
scanf("%d",&n);
x=(int*)malloc(sizeof(int)*n);
y=(int*)malloc(sizeof(int)*n);
printf("The number of x and y\n");
for(i=0;i<n;i++){
scanf("%d",&x[i]);
scanf("%d",&y[i]);
if(map[x[i]-1+6][y[i]-1+6]==0){
map[x[i]-1+6][y[i]-1+6]=3;
}
else if(map[x[i]-1+6][y[i]-1+6]==1){
map[x[i]-1+6][y[i]-1+6]=6;
}
}//for
//冒泡法
sort(x,n);
sort(y,n);
//求中位数
int Med_x=0,Med_y=0;
int juli=0;
Med_x=Median(x,n);
Med_y=Median(y,n);
if(map[Med_x-1+6][Med_y-1+6]==0){
map[Med_x-1+6][Med_y-1+6]=2;
}
else if(map[Med_x-1+6][Med_y-1+6]==1){
map[Med_x-1+6][Med_y-1+6]=4;
}
else if(map[Med_x-1+6][Med_y-1+6]==3){
map[Med_x-1+6][Med_y-1+6]=5;
}
for(i=0;i<n;i++){
juli=juli+abs(Med_x-x[i]);
}
for(i=0;i<n;i++){
juli=juli+abs(Med_y-y[i]);
}
printf("%d\n",juli);
for(j=11;j>=0;j--){
for(i=0;i<12;i++){
if(map[i][j]==0){
printf(" ^ ");
}//if0
else if(map[i][j]==1){
printf(" 0 ");
}//if1
else if(map[i][j]==2){
printf(" S ");
}//if2
else if(map[i][j]==3){
printf(" P ");
}//if3
else if(map[i][j]==4){
printf(" h ");
}//if1
else if(map[i][j]==5){
printf(" y ");
}//if1
else if(map[i][j]==6){
printf(" m ");
}//if1
}//for2
printf("\n");
}//for1
return 0;
}//main
实验结果:
实验输入
实验输出: