庞果网之建立信号基站

题目详情

要建立一个信号基站服务n个村庄,这n个村庄用平面上的n个点表示。假设基站建立的位置在(X,Y),则它对某个村庄(x,y)的距离为max{|X – x|, |Y – y|}, 其中| |表示绝对值,我们的目标是让所有村庄到信号基站的距离和最小。

基站可以建立在任何实数坐标位置上,也可以与某村庄重合。

输入

给定每个村庄的位置x[],y[],x,y都是整数,满足:

           -1000000000 < x,y < 1000000000

村庄个数大于1,小于101。

输出

所有村庄到信号基站的距离和的最小值。

关于精度:

因为输出是double。我们这样判断对错,如果标准答案是A,你的答案是a,如果|A – a| < 1e-3 我们认为是正确的,否则认为是错误的。

样例

假设有4个村庄位置分别为 (1,4) (2,3) (0,1) (1,1)

我们的结果是5。因为我们可以选择(1.5,2.5)来建立信号基站。

bestDistance = max(|1.5-1|, |2.5-4|) + max(|1.5-2|,|2.5-3|) + max(|1.5-0|,|2.5-1|) + max(|1.5-1|,|2.5-1|)

= max(0.5, 1.5) + max(0.5,0.5) + max(1.5,1.5) + max(0.5,1.5)

= 1.5 + 0.5 + 1.5 + 1.5

= 5

/*********************************
*   日期:2013-11-14
*   作者:SJF0115
*   题号: 题目 建立信号基站
*   来源:http://hero.pongo.cn/Question/Details?ID=81&ExamID=79
*   结果:AC
*   来源:庞果网
*   总结:
**********************************/
#include<iostream>
#include<stdio.h>
#include<string>
using namespace std;

double bestDistance(int n, const int *x, const int *y){
	int i,index,temp,j;
	double result,min1 = 0,min2 = 0,min3 = 0,min4 = 0;
	int *sum,*difference;
    sum = (int *)malloc(sizeof(int) * n);
    difference = (int *)malloc(sizeof(int) * n);
	//计算和差
	for(i = 0;i < n;i++){
		sum[i] = x[i] + y[i];
		difference[i] = x[i] - y[i];
	}
	//排序(从小到大)
	for(i = 0;i < n - 1;i++){
        for(j = i + 1;j < n;j++){
            if(sum[i] > sum[j])
            {
                temp = sum[i];
                sum[i] = sum[j];
                sum[j] = temp;
            }
        }
    }
	for(i = 0;i < n - 1;i++){
        for(j = i + 1;j < n;j++){
            if(difference[i] > difference[j])
            {
                temp = difference[i];
                difference[i] = difference[j];
                difference[j] = temp;
            }
        }
    }

	index = n / 2 - 1;
	for(i = 0;i <= index;i++){
		min1 += sum[i];
		min2 += difference[i];
	}
	//判断n奇偶性
	if(n % 2 == 0){
		index = n / 2;
	}
	else{
		index = n / 2 + 1;
	}
	for(i = index;i <= n-1;i++){
		min3 += sum[i];
		min4 += difference[i];
	}
	result = (min3 - min1 + min4 - min2) / 2.0;
	return result;
}

int main()
{
	/*int i,n;
	int x[101],y[101];
	while(scanf("%d",&n) != EOF){
		for(i = 0;i < n;i++){
			scanf("%d %d",&x[i],&y[i]);
		}
		printf("%lf\n",bestDistance(n,x,y));
	}*/
	int x[] = {858442934,-161749718,-55910439,347569202,-660170269,-982075453,-860790164,947179323,312298821,-285196111,967545126,-777105315,-630974471,-713895350,745616673,840630174,-597730146,-205693089,24677872};
	int y[] = {449535070,160026431,705809990,121634879,648304545,-392329548,-447666131,-829918127,926665890,943182185,601133076,-848803337,89719473,-586785144,832132969,-111884761,-556530757,65860874,978639057};
	int n = 19;
	printf("%lf\n",bestDistance(n,x,y));
    return 0;
}

【解析】:

解题的关键在于如何处理max{|X – x|, |Y – y|},可以通过分段函数讨论来证明,max{|x1-x2|,|y1-y2|},等价于(|x1+y1-x2-y2|+|x1-y1-(x2-y2)|)/2;

  假设信号基站的坐标是(X , Y),那么他与其他坐标的距离为max{|X – x1|, |Y – y1|} = (|X+Y-x1-y1|+|X-Y-(x1-y1)|)/2, ……,(|X+Y-xn-yn|+|X-Y-(xn-yn)|)/2;也就是最短距离

  bestDistance = 1/2  * (|X+Y-(x1+y1)| + |X-Y-(x1-y1)| + |X+Y-(x2+y2)| + |X-Y-(x2-y2)| +……+ |X+Y-(xn+yn)|+|X-Y-( xn-yn)|)
-- (1-1)

  其中,x1+y1 、x1-y1  、 x2+y2
、 
x2-y2 、……、xn+yn  、 xn-yn 均为常数,
通过题目所给的数组可以容易得到这些值

  假设 U(X, Y) = X + Y ,       V(X, Y) = X - Y ;可以得到

  bestDistance =  1/2  *(|U - U1| + |V - V1| + |U - U2| + |V - V2| + ……+ |U - Un| + |V - Vn|)    -- (1 - 2)

     = 1/2  *【(|U - U1| + |U - U2| + ……+ |U - Un|) + (|V - V1|  + |V - V2| + ……+ |U - Un| + |V - Vn|) 】

  这样,就转换为求函数 y = |x - x1| +  |x - x2| +  |x - x3| + ……+ |x - xn|的最小值的问题,也许有人会问,公式(1 - 2)有两个变量U , V,而函数y只有一个变量x,其实很好办,就将公式(1 - 2)按照变量 和 V分为两部分,分别求最小值,和起来也肯定是最小值;

  对于函数 y = |x - x1| +  |x - x2| +  |x - x3| + ……+ |x - xn| (x1 , x2, ……xn是从小到大排列)的最小值;可以用数学归纳法求解:

  证明:假设n = 2,则 y = |x - x1| +  |x - x2|,假设 x< x,当x ≤x< x时,y = x1 + x2 - 2x , ymin = x2- x1; 当 x1< x < x2时,

y  = x2 - x1 ,则ymin = x2 - x1 ; 当 x ≥ x2 时,y = 2x - x1 - x2, ymin = x2 - x1;

  若 n > 2 ,

  当x < x1 < x2 <……< xn 时,y = (x1 - x) + (x2 - x) +…… +(xn - x) = (x1 + x2 + x3 +……+ xn) - n * x;

  当x1 < x < x2 <……< xn 时,y =  (x1 + x2 + x3 + …… + xn) - n * x + 2(x - x1);

  当x1 < x2 < x <……< xn 时,y =  (x1 + x2 + x3 + …… + xn) - n * x + 2[(x - x1) + (x - x2)];

  ……

  所以,当x1 < x2 < …xk < x < xk+1 <…< xn 时,

  y =  (x1 + x2 + x3 + …… + xn) - n * x + 2[(x - x1) + (x - x2) + ……+ (x - xk)]

   =  (x1 + x2 + x3 + …… + xn)  +  2[ (k - n/2)x - (x1 + x2 + ……+  xk) ]  --(1 - 4)

  对于公式(1 - 4),两边求导,可知当k - n/2 < 0 时,即k < n/2时,y 单调递增; 当k - n/2 > 0 时,即k > n/2时,y 单调递减;因为k= {1,2,3,……n},为整数,若 n 为偶数,则当 k = n/2 时,x = xk有最小值;若 为 奇数,则当 k = (n + 1)/2时,x = xk有最小值,证毕

  综上所述,得到的最终结论是:当 n 为偶数时,y的最小值为ymin = (xk+1 + xk+2 + ……+xn) - (x1 + x2 +……+ xk) , k = n/2 ;当 n 为奇数时,y的最小值为ymin =
(xk+1 + xk+2 + ……+xn) - (x1 + x2 +……+ xk - 1) , k = (n + 1)/2 .

  回到公式(1 - 2),分别求出(|U - U1| + |U - U2| + ……+ |U - Un|) 和 (|V - V1|  + |V - V2| + ……+ |U - Un| + |V - Vn|)的最小值,求平均数,即得到最小值bestDistance ,为程序所求.

来源:点击打开链接

时间: 2024-10-29 16:18:22

庞果网之建立信号基站的相关文章

庞果网之高斯公式

[题目] 题目详情 高斯在上小学时发明了等差数列求和公式:1+2+..+100=5050.现在问题在于给你一个正整数n,问你他可以表示为多少种连续正整数之和?(自身也算). 输入格式: 多组数据,每组数据一行,一个正整数n. 0<n<2000000000 输出格式: 每组数据一行,包含一个正整数,表示结果. 答题说明 输入样例 5 120 输出样例: 2 4 解释: 5=2+3=5 120=1+2+...+15=22+23+24+25+26=39+40+41=120 [分析] 具体详见:点击打

庞果网之寻找直方图中面积最大的矩形

题目详情 给定直方图,每一小块的height由N个非负整数所确定,每一小块的width都为1,请找出直方图中面积最大的矩形.    如下图所示,直方图中每一块的宽度都是1,每一块给定的高度分别是[2,1,5,6,2,3]:    那么上述直方图中,面积最大的矩形便是下图所示的阴影部分的面积,面积= 10单位.    请完成函数largestRectangleArea,实现寻找直方图中面积最大的矩形的功能,如当给定直方图各小块的高度= [2,1,5,6,2,3] ,返回10. [解析] 使用一个栈

庞果网之字符串消除

题目详情 给定一个字符串,仅由a,b,c 3种小写字母组成.当出现连续两个不同的字母时,你可以用另外一个字母替换它,如 有ab或ba连续出现,你把它们替换为字母c: 有ac或ca连续出现时,你可以把它们替换为字母b: 有bc或cb 连续出现时,你可以把它们替换为字母a. 你可以不断反复按照这个规则进行替换,你的目标是使得最终结果所得到的字符串尽可能短,求最终结果的最短长度. 输入:字符串.长度不超过200,仅由abc三种小写字母组成. 输出: 按照上述规则不断消除替换,所得到的字符串最短的长度.

庞果网之字符串的完美度

题目详情 我们要给每个字母配一个1-26之间的整数,具体怎么分配由你决定,但不同字母的完美度不同, 而一个字符串的完美度等于它里面所有字母的完美度之和,且不在乎字母大小写,也就是说字母F和f的完美度是一样的. 现在给定一个字符串,输出它的最大可能的完美度. 例如:dad,你可以将26分配给d,25分配给a,这样整个字符串最大可能的完美度为77. /********************************* * 日期:2013-11-03 * 作者:SJF0115 * 题号: 题目 字符串

庞果网之素因子集合

[题目] 题目详情 小强最近在学初等数论,老师给他们出了一个课后习题,那就是给你两个正整数A,B(0<A,B<2^60),判断他们的素因子集合是否相同,小强刚接触数论,想了好一会还是没能想出来,你能帮助他吗? 输入描述: 输入包含多组测试数据,每组测试数据包含两个正整数A,B,以文件结束. 输出描述: 对于每组测试数据如果A和B的素因子集合相同则输出"YES",否则输出"NO". 答题说明 输入样例: 2 8 4 9 10 50 输出样例: YES NO

庞果网之杨辉三角的变形

题目详情          1      1   1  1   1  2   3  2  1 1  3  6   7  6  3  1 以上三角形的数阵,第一行只有一个数1, 以下每行的每个数,是恰好是它上面的数,左上的数和右上数等3个数之和(如果不存在某个数,认为该数就是0). 求第n行第一个偶数出现的位置.如果没有偶数,则输出-1.例如输入3,则输出2,输入4则输出3. 输入n(n <= 1000000000) [解析] 经过分析得出的结论如下: 1.前两行没有偶数可直接返回-1 2.一下每

庞果网之数组排序

题目详情 本题来自caopengcs,只要你有兴趣,每个人都可以出题(出题入口在主页右侧边栏"贡献题目"->"我要发布"内),以下是题目详情: 给定一个包含1-n的数列,我们通过交换任意两个元素给数列重新排序.求最少需要多少次交换,能把数组排成按1-n递增的顺序,其中,数组长度不超过100. 例如: 原数组是3,2,1, 我们只需要交换1和3就行了,交换次数为1,所以输出1. 原数组是2,3,1,我们需要交换2和1,变成1,3,2,再交换3和2,变为1,2,3

豆果网王宇翔:制造走进厨房的冲动

中介交易 SEO诊断 淘宝客 云主机 技术大厅 2007年,夏天,王宇翔对三位朋友说:"我有一个做美食社区的想法,你们是不是愿意跟我做?"就这样王宇翔和他的朋友们开始了美食创业的历程. 豆果网创始人 王宇翔 诱惑与专注 刚开始创业时,王宇翔希望做的是美食社区,起名叫做"我菜网".没过多久,王宇翔就发现想法和现实之间的差距:没有资金.没有人帮助,这个美食项目是不是真的前途渺茫? 曾经有一段时候,我菜网打算转型:从纯粹的做美食,转到做"吃.喝.玩"的

服务器-不进行端口映射如何向内网计算机建立TCP链接?

问题描述 不进行端口映射如何向内网计算机建立TCP链接? 小弟初学socket编程,尝试了一下建立TCP链接,局域网内很容易,但在广域网上,因为作为服务器的计算机是在内网中,所以只有在路由器中做了端口映射之后才能建立TCP链接.所以想问一下各位大神,如何才能在不进行端口映射的情况下建立TCP链接?我看很多点对点的网络游戏并没有要求对路由器进行设置,还请各位指教 解决方案 需要有公网IP(其中一台机器有公网IP,两台都有就不用说了)或者有一个中间服务器是有公网IP(做NAT穿透),否则没办法 解决