2014-05-08 05:16

题目链接

原题:

Given a circle with N defined points and a point M outside the circle, find the point that is closest to M among the set of N. O(LogN)

题目:给定一个圆上的N个点,和一个在这个圆外部的点。请找出这N个点中与外部点最近的那个。要求时间复杂度是对数级的。

解法1:这位“Guy”老兄又出了一道莫名奇妙的题:1. 这些点是等距离的吗?2. 这些点是顺时针还是逆时针排列的?在没有比较清楚思路的情况下,我只写了个O(n)枚举的算法。

代码:

 // http://www.careercup.com/question?id=4877486110277632
#include <cmath>
#include <iostream>
#include <vector>
using namespace std; struct Point {
double x;
double y;
Point(double _x = , double _y = ): x(_x), y(_y) {};
}; double dist(const Point &p1, const Point &p2)
{
return sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y));
} int main()
{
int i, n;
Point pout;
vector<Point> vp;
int min_i;
double d, min_d; while (cin >> n && n > ) {
vp.resize(n);
for (i = ; i < n; ++i) {
cin >> vp[i].x >> vp[i].y;
}
cin >> pout.x >> pout.y; min_i = ;
min_d = dist(pout, vp[]);
for (i = ; i < n; ++i) {
d = dist(pout, vp[i]);
min_i = d < min_d ? i : min_i;
}
cout << '(' << vp[min_i].x << ',' << vp[min_i].y << ')' << endl;
cout << min_d << endl;
vp.clear();
} return ;
}

解法2:实际上这题不但有对数级算法,还有常数级算法。但有一个额外条件需要满足:我得知道圆心在哪儿。计算圆心需要把所有点的坐标求平均值,那样的算法复杂度还是线性的。如果我们定义P[i]为圆上的那N个点,O为圆心,M为圆外的那个点。那么我们连接OP[i]与OM,可以发现OM与OP[i]的夹角分布是循环有序的(参见Leetcode里面的Rotated Sorted Array),条件是这N个点呈顺时针或逆时针分布。你可以通过二分得到距离最小的结果,但更快的算法是常数级的。你只要计算一个夹角,就知道所有的了。因为这些夹角是个等差数列。比如四个点中,有一个的夹角是73°,那么另外三个肯定是163°、107°(253°)、17°(343°)。谁的距离最短呢?角度最小的就是了,注意优角要换算成锐角或钝角。想要通过一次计算就解决问题,用除法和取模的思想吧。此处的代码默认点是按照顺时针排列的,否则为了判断哪个方向,又得进行一些计算。那样的话,代码都乱的看不清楚了。

代码:

 // http://www.careercup.com/question?id=4877486110277632
#include <cmath>
#include <iostream>
#include <vector>
using namespace std; struct Point {
double x;
double y;
Point(double _x = , double _y = ): x(_x), y(_y) {}; Point operator - (const Point &other) {
return Point(x - other.x, y - other.y);
}; Point operator + (const Point &other) {
return Point(x + other.x, y + other.y);
}; double operator * (const Point &other) {
return x * other.x + y * other.y;
};
}; double dist(const Point &p1, const Point &p2)
{
return sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y));
} int main()
{
int i, n;
Point pout;
vector<Point> vp;
Point center;
Point v0, vout;
// the angle between OM and a line of center
double angle;
// 2 * pi / n
double side_angle;
const double pi = 3.1415926;
double d; while (cin >> n && n > ) {
vp.resize(n);
for (i = ; i < n; ++i) {
cin >> vp[i].x >> vp[i].y; }
cin >> center.x >> center.y;
cin >> pout.x >> pout.y; v0 = vp[] - center;
vout = pout - center; side_angle = * pi / n;
angle = arccos((v0 * vout) / (dist(vp[], center) * dist(pout, center)));
d = angle / side_angle;
// Here I assume the points are arranged in clockwise order.
i = d - floor(d) < 0.5 ? floor(d) : floor(d) + ;
cout << vp[i].x << ' ' << vp[i].y << endl; vp.clear();
} return ;
}

Careercup - Google面试题 - 4877486110277632的更多相关文章

  1. Careercup - Google面试题 - 5732809947742208

    2014-05-03 22:10 题目链接 原题: Given a dictionary, and a list of letters ( or consider as a string), find ...

  2. Careercup - Google面试题 - 5085331422445568

    2014-05-08 23:45 题目链接 原题: How would you use Dijkstra's algorithm to solve travel salesman problem, w ...

  3. Careercup - Google面试题 - 4847954317803520

    2014-05-08 21:33 题目链接 原题: largest number that an int variable can fit given a memory of certain size ...

  4. Careercup - Google面试题 - 6332750214725632

    2014-05-06 10:18 题目链接 原题: Given a ,) (,) (,), (,) should be returned. Some suggest to use Interval T ...

  5. Careercup - Google面试题 - 5634470967246848

    2014-05-06 07:11 题目链接 原题: Find a shortest path ,) to (N,N), assume is destination, use memorization ...

  6. Careercup - Google面试题 - 5680330589601792

    2014-05-08 23:18 题目链接 原题: If you have data coming in rapid succession what is the best way of dealin ...

  7. Careercup - Google面试题 - 5424071030341632

    2014-05-08 22:55 题目链接 原题: Given a list of strings. Produce a list of the longest common suffixes. If ...

  8. Careercup - Google面试题 - 5377673471721472

    2014-05-08 22:42 题目链接 原题: How would you split a search query across multiple machines? 题目:如何把一个搜索que ...

  9. Careercup - Google面试题 - 6331648220069888

    2014-05-08 22:27 题目链接 原题: What's the tracking algorithm of nearest location to some friends that are ...

随机推荐

  1. 标准的CSS盒子模型?与低版本IE的盒子模型有什么不同的?

    CSS盒子模型:由四个属性组成的外边距(margin).内边距(padding).边界(border).内容区(width和height); 标准的CSS盒子模型和低端IE CSS盒子模型不同:宽高不 ...

  2. 软件工程 speedsnail 第二次冲刺3

    20150520 完成任务:划线第三天,能画出一条直黄线且与蜗牛共存: 遇到问题: 问题1 碰撞检测有缺陷 解决1 没有解决 明日任务: 实现蜗牛与线的碰撞

  3. Run JavaScript on your PeopleSoft pages conditionally

    Here, PeopleCode sets the logic that determines when the JavaScript code will run. This is not as si ...

  4. winform 自定义控件以及委托事件的使用

    源代码:http://files.cnblogs.com/files/qtiger/%E8%AE%A1%E7%AE%97%E5%99%A8%E5%AE%89%E8%A3%85%E5%8C%85%E4% ...

  5. SQL中补0

     SQL中补0 编写人:CC阿爸 2014-3-14 第一种方法: right('00000'+cast(@count as varchar),5) 其中'00000'的个数为right函数的最后参数 ...

  6. CentOS用户权限管理--su与sudo

    Linux权限管理--su与sudo 1.su用来切换登录的用户,比如当前用户为chen,可以用su zhu,并输入用户zhu的登录密码,就可以切换到用户zhu.如果一个普通用户想切换到root用户, ...

  7. 在xml中添加array

    在values建立arrays(名字可自定义)的xml: <?xml version="1.0" encoding="utf-8"?> <re ...

  8. Eclipse之Failed to load the JNI shared library”……\jvm.dll”的解决方案

    问题描述:java环境变量配置完全正确,但是运行eclipse时提示:Failed to load the JNI shared library " xxx\jva.dll" 原因 ...

  9. Toast提示信息

    用Toast来作为操作成功以及用户误操作等等的提示,非常的简单.直接上代码: 创建方式一: ps: 此处没有设置toast的其他属性,均使用默认的风格(个人觉得默认的风格除了字体比较小之外 还是挺好看 ...

  10. about the pageload and page init event

    Page_Init The Page_Init event is the first to occur when an ASP.NET page is executed. This is where ...