Careercup - Facebook面试题 - 4907555595747328
2014-05-02 07:49
原题:
Given a set of n points (coordinate in 2d plane) within a rectangular space, find out a line (ax+by=c), from which the sum of the perpendicular distances of all the points will be minimum. This can has a general usecase like, in a village there are few house, you have to lay a road, such that sum of all the approach roads from each house will be minimum.
题目:给定二维平面上的n个点,请找到一条直线,使得这些点到这条直线的距离之和最小。
解法:点到直线的距离是|a * x + b * y + c| / sqrt(a * a + b * b)。那么这个距离之和就是一堆绝对值的和。你可能很快会想到线性回归的那幅图片:一堆点均匀分散在一条直线的两侧。很遗憾,这个不是最优解,因为最小二乘满足的条件是方差最小,也就是平方和最小(学过线性代数应该知道p-范数的概念,平方和再开方就是2-范数。而范数,就是线性空间里对长度的度量算子。范数最小的时候,也就是我们用最小二乘期待的结果)。平方和最小和绝对值和最小并非同一概念。那么绝对值的和什么时候最小呢?我找到了一篇不太知名的论文,源头链接在此(里面有人提到了那篇论文的链接,我不直接贴链接是因为那人直接把论文内容贴了出来,有侵权嫌疑)。证明实在太绕了,所以我没工夫仔细推理完,只是偷懒引用了其中的一个结论:满足距离之和最短的直线,一定会穿过n个点中的两点。有这个结论,就可以用两层循环遍历所有的直线组合,然后再用一层循环计算所有点的距离。选取距离之和最小的那条直线作为结果。这样写出来的算法,时间复杂度是O(n^3)的。看来不靠谱,但好歹是个解法吧。如果你用最小二乘法来做,时间复杂度应该是O(n^2)的,我相信得到的就算不是最优解,也应该很接近。所以有时你连算法都拿不准的时候,还不如用次优解来代替最优解,因为其他方面的优势可以作为权衡因素。
代码:
// http://www.careercup.com/question?id=4907555595747328
#include <cmath>
#include <iomanip>
#include <iostream>
#include <vector>
using namespace std; struct Line {
double a;
double b;
double c;
Line(double _a = , double _b = , double _c = ): a(_a), b(_b), c(_c) {};
}; struct Point {
double x;
double y;
Point(double _x = , double _y = ): x(_x), y(_y) {};
}; double calcDist(const Point &p, const Line &line)
{
return abs(line.a * p.x + line.b * p.y + line.c) / sqrt(line.a * line.a + line.b * line.b);
} void calcLine(const Point &p1, const Point &p2, Line &line)
{
line.a = p2.y - p1.y;
line.b = p1.x - p2.x;
line.c = -((line.a * p1.x + line.b * p1.y) + (line.a * p2.x + line.b * p2.y)) / 2.0;
} int main()
{
vector<Point> p;
int n;
Line line, min_line;
int i, j, k;
double dist, min_dist; while (cin >> n && n > ) {
p.resize(n);
for (i = ; i < n; ++i) {
cin >> p[i].x >> p[i].y;
} do {
if (n == ) {
line = Line(, , -p[].y);
break;
} else if (n == ) {
min_dist = ;
calcLine(p[], p[], min_line);
break;
} min_dist = -;
for (i = ; i < n; ++i) {
for (j = i + ; j < n; ++j) {
dist = ;
calcLine(p[i], p[j], line);
for (k = ; k < n; ++k) {
if (k == i && k == j) {
continue;
}
dist += calcDist(p[k], line);
}
if (min_dist < || dist < min_dist) {
min_dist = dist;
min_line = line;
}
}
}
} while (); if (min_line.a != 0.0) {
cout << min_line.a << 'x';
}
if (min_line.b != 0.0) {
cout << setiosflags(ios::showpos) << min_line.b << 'y';
}
if (min_line.c != 0.0) {
cout << min_line.c;
}
cout << resetiosflags(ios::showpos) << "=0" << endl;
cout << min_dist << endl;
} return ;
}
Careercup - Facebook面试题 - 4907555595747328的更多相关文章
- Careercup - Facebook面试题 - 6026101998485504
2014-05-02 10:47 题目链接 原题: Given an unordered array of positive integers, create an algorithm that ma ...
- Careercup - Facebook面试题 - 5344154741637120
2014-05-02 10:40 题目链接 原题: Sink Zero in Binary Tree. Swap zero value of a node with non-zero value of ...
- Careercup - Facebook面试题 - 5765850736885760
2014-05-02 10:07 题目链接 原题: Mapping ' = 'A','B','C' ' = 'D','E','F' ... ' = input: output :ouput = [AA ...
- Careercup - Facebook面试题 - 5733320654585856
2014-05-02 09:59 题目链接 原题: Group Anagrams input = ["star, astr, car, rac, st"] output = [[& ...
- Careercup - Facebook面试题 - 4892713614835712
2014-05-02 09:54 题目链接 原题: You have two numbers decomposed in binary representation, write a function ...
- Careercup - Facebook面试题 - 6321181669982208
2014-05-02 09:40 题目链接 原题: Given a number N, write a program that returns all possible combinations o ...
- Careercup - Facebook面试题 - 5177378863054848
2014-05-02 08:29 题目链接 原题: Write a function for retrieving the total number of substring palindromes. ...
- Careercup - Facebook面试题 - 5435439490007040
2014-05-02 07:37 题目链接 原题: // merge sorted arrays 'a' and 'b', each with 'length' elements, // in-pla ...
- Careercup - Facebook面试题 - 5188884744896512
2014-05-02 07:18 题目链接 原题: boolean isBST(const Node* node) { // return true iff the tree with root 'n ...
随机推荐
- nodejs4-模块和包
模块和包: 定义模块的方法跟sea.js类似,暴露一个接口也是使用exports. 调用一个接口就是使用require 注意:在引入模块的时候如果是同级目录需要加./,否则会报错 除了可以使用ex ...
- Activity之间传递数据或数据包Bundle,传递对象,对象序列化,对象实现Parcelable接口
package com.gaojinhua.android.activitymsg; import android.content.Intent; import android.os.Bundle; ...
- 番外篇 之 C#委托
对于上一节 番外篇之C#多线程的反思 反思一: Thread th = new Thread(参数); ////参数的总结 ////首先,第一情况,对于 Thread th = new Threa ...
- 原生js学习笔记2
知识点: 1:关于this指向问题,如果有函数a(),直接a()那么this指向window,new a()指向函数本身. 2:关于null和undefined.两者如果用“==”则认为两者是相等的, ...
- [转]GCC参数详解
[介绍] gcc and g++分别是gnu的c & c++编译器 gcc/g++在执行编译工作的时候,总共需要4步 1.预处理,生成.i的文件[预处理器cpp] 2.将预处理后的文件不转换成 ...
- AMQ学习笔记 - 10. Spring-JmsTemplate之浏览
概述 浏览只是针对Queue的概念,Topic没有浏览.浏览是指获取消息而消息依然保持在broker中,而消息的接收会把消息从broker中移除. 浏览可以用来实现对Queue中消息的监控. JMS ...
- (转)LR监控Linux系统性能计数器详解
从LR里面add measurement,填写linux机器的IP,出现所有unix/linux的计数器,包括cpu的,mem的,disk,network的.这里介绍几个常用的: (对于如何监控Lin ...
- CSS3伪类
1.:last-child 比如:查找ul的最后一个li ul li:last-child { //样式 } 2.:first-child 比如:查找ul的第一个li ul li:first-chil ...
- android 网络_网络源码查看器
xml设计 <?xml version="1.0"?> -<LinearLayout tools:context=".MainActivity" ...
- Codevs 1081 线段树练习2
时间限制: 1 s 空间限制: 128000 KB 题目等级 : 大师 Master 题目描述 Description 给你N个数,有两种操作 1:给区间[a,b]的所有数都增加X 2:询问第 ...