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 ...
随机推荐
- 集合类学习之Hashmap机制研究
1.遍历的两种实现方法 //新建 Map map=new HashMap(); //存储值 map.put() ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 //遍历方式 ...
- [Android开发系列]IT博客应用V1.3
首先,感谢使用这款软件并给我意见的朋友们,有你们的意见,才有了这个版本. 其次,检索功能和分类筛选功能(如果是你提的意见,记得在下面mark哦,毕竟读代码你能发现,其实发意见这个就是用自己的邮箱给自己 ...
- 搭建Cocos2d-JS开发环境
使用Cocos2d-JS引擎开发游戏,主要的程序代码是JavaScript语言,因此,凡是能够开发JavaScript语言工具都适用于Cocos2d-JS游戏开发.本书我们推荐WebStorm和Coc ...
- 如何给xml应用样式
引子:可扩展标记语言xml(Extensible Markup Language)自己平常也用到的不多,除了在ajax处理服务器返回的数据可能会用到外(不过一般用json处理数据的比较常见)还真没怎么 ...
- Requirejs学习笔记(一)
中文api 和 英文api网上都有的我就不翻译了,我的学习方法是先看英文api,然后看不懂的就比对中文api看一遍. requirejs可以帮助js代码模块化开发,模块化意味了解决了代码凌乱的问题,方 ...
- 使用原生Sql查询实现按分类推送最新文章到首页
一般在网站的首页都会有网站最新文章的推送,而这些文章又属于不同的分类.如果某个分类的文章突然集中在一个时间段发布,那么就会造成首页上所有文章都是该分类的文章,其他的文章分类就变成不可见的了.所以,我希 ...
- 《shell下sort排序命令的使用》
首先建立一个文件,很乱,没有规律: 正排序: 倒排序: Uniq 删除文件中的重复行:用此命令要先对文件进行排序. 对文件冗余,只要文件所有重复的字符显示一次: 显示1-7,不重复的行: 只显示1-7 ...
- C++ const用法小结 (欢迎大家拍砖)
C++const 关键字小结 const 是constant的缩写,本意是不变的,不易改变的意思. const 在C++中是用来修饰内置类型变量,自定义对象,成员函数,返回值,函数参数. 一.cons ...
- memcached/redis安全性
最近看到说redis,memcached服务器安全的问题,想想也是,使用这两种服务N年了,由于历史问题吧,工作中基本是以memcached为主,后来才慢慢引入运用redis.由于memcached是没 ...
- Linux5.8下安装PhpMyadmin无法关联php-mcrypt问题
一.yum安装php-mcrypt ##发现没办法安装 原来CentOS 官方默认不在对mcrypt模块 进行支持,所以必须另想办法折腾了2个小时总算搞定,这里主要使用了Fedora的扩展库, E ...