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)枚举的算法。

代码:

 1 // http://www.careercup.com/question?id=4877486110277632
 2 #include <cmath>
 3 #include <iostream>
 4 #include <vector>
 5 using namespace std;
 6
 7 struct Point {
 8     double x;
 9     double y;
10     Point(double _x = 0, double _y = 0): x(_x), y(_y) {};
11 };
12
13 double dist(const Point &p1, const Point &p2)
14 {
15     return sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y));
16 }
17
18 int main()
19 {
20     int i, n;
21     Point pout;
22     vector<Point> vp;
23     int min_i;
24     double d, min_d;
25
26     while (cin >> n && n > 0) {
27         vp.resize(n);
28         for (i = 0; i < n; ++i) {
29             cin >> vp[i].x >> vp[i].y;
30         }
31         cin >> pout.x >> pout.y;
32
33         min_i = 0;
34         min_d = dist(pout, vp[0]);
35         for (i = 1; i < n; ++i) {
36             d = dist(pout, vp[i]);
37             min_i = d < min_d ? i : min_i;
38         }
39         cout << '(' << vp[min_i].x << ',' << vp[min_i].y << ')' << endl;
40         cout << min_d << endl;
41         vp.clear();
42     }
43
44     return 0;
45 }

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

代码:

 1 // http://www.careercup.com/question?id=4877486110277632
 2 #include <cmath>
 3 #include <iostream>
 4 #include <vector>
 5 using namespace std;
 6
 7 struct Point {
 8     double x;
 9     double y;
10     Point(double _x = 0, double _y = 0): x(_x), y(_y) {};
11
12     Point operator - (const Point &other) {
13         return Point(x - other.x, y - other.y);
14     };
15
16     Point operator + (const Point &other) {
17         return Point(x + other.x, y + other.y);
18     };
19
20     double operator * (const Point &other) {
21         return x * other.x + y * other.y;
22     };
23 };
24
25 double dist(const Point &p1, const Point &p2)
26 {
27     return sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y));
28 }
29
30 int main()
31 {
32     int i, n;
33     Point pout;
34     vector<Point> vp;
35     Point center;
36     Point v0, vout;
37     // the angle between OM and a line of center
38     double angle;
39     // 2 * pi / n
40     double side_angle;
41     const double pi = 3.1415926;
42     double d;
43
44     while (cin >> n && n > 0) {
45         vp.resize(n);
46         for (i = 0; i < n; ++i) {
47             cin >> vp[i].x >> vp[i].y;
48
49         }
50         cin >> center.x >> center.y;
51         cin >> pout.x >> pout.y;
52
53         v0 = vp[0] - center;
54         vout = pout - center;
55
56         side_angle = 2 * pi / n;
57         angle = arccos((v0 * vout) / (dist(vp[0], center) * dist(pout, center)));
58         d = angle / side_angle;
59         // Here I assume the points are arranged in clockwise order.
60         i = d - floor(d) < 0.5 ? floor(d) : floor(d) + 1;
61         cout << vp[i].x << ' ' << vp[i].y << endl;
62
63         vp.clear();
64     }
65
66     return 0;
67 }

转载于:https://www.cnblogs.com/zhuli19901106/p/3715309.html

Careercup - Google面试题 - 4877486110277632相关推荐

  1. Careercup - Google面试题 - 4699414551592960

    2014-05-06 13:34 题目链接 原题: we have a random list of people. each person knows his own height and the ...

  2. Careercup - Google面试题 - 5424071030341632

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

  3. Careercup - Google面试题 - 5377673471721472

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

  4. Google 面试题和详解

    Google的面试题在刁钻古怪方面相当出名,甚至已经有些被神化的味道.这个话题已经探讨过很多次,而科技博客 BusinessInsider这两天先是贴出15道Google面试题并一一给出了答案,其中不 ...

  5. 【Google面试题】有四个线程1、2、3、4同步写入数据…C++11实现

    Google面试题 有四个线程1.2.3.4.线程1的功能就是输出1,线程2的功能就是输出2,以此类推-现在有四个文件ABCD.初始都为空.现要让四个文件呈如下格式: A:1 2 3 4 1 2- B ...

  6. Google面试题之100层仍两个棋子

    一道Google面试题,题目如下:"有一个100层高的大厦,你手中有两个相同的玻璃围棋子.从这个大厦的某一层扔下围棋子就会碎,用你手中的这两个玻璃围棋子,找出一个最优的策略,来得知那个临界层 ...

  7. Google面试题:找几百亿数据的中值

    Google面试题:找几百亿数据的中值 http://blog.csdn.net/jiyanfeng1/article/details/8088237 有几百亿的整数,分布的存储到几百台通过网络连接的 ...

  8. google面试题,生男生女比例?

    Google面试题: 在一个重男轻女的国家里,每个家庭都想生男孩,如果他们生的孩子是女孩,就再生一个,直到生下的是男孩为止,这样的国家,男女比例会是多少? 答案:1:1 分析:  出生男女概率是50% ...

  9. 扔玻璃球 [ Google面试题 ]

    这是一道 Google 面试题,考察的是对于 粗调 和 精调 工程思维 对于扔玻璃球国内也叫扔鸡蛋. ta不用您有什么基础,只需要一个基本工程思维. 粗调和精调,这个已是统计学里最优法,所以不用担心复 ...

最新文章

  1. php的基本语法和数据类型
  2. c 调用java的dll_Windows下java调用c的dll动态库--Dev_Cpp编译c生成dll
  3. VB中判断空的几种方法,Null, Missing, Empty, Nothing, vbNullString区别
  4. boost::mpi模块实现测试mpi版本
  5. access violation at address in module Read of address
  6. android 跳转到小米手机神隐模式
  7. java 接口中变量修饰符,Java的访问修饰符与变量的作用域讲解
  8. Angular 7 和 .Net Core 2.2——全球天气(第1部分)
  9. 多线程android代码,android入门 — 多线程(一)(示例代码)
  10. 虚拟化技术天书:九宫格图解虚拟化——此文多风险,阅读需谨慎
  11. 非法关机linux分辨率丢失,非法关机造成文件系统损坏,怎么办?请教:附图片...
  12. 软考 信息安全工程师(第二版)笔记-第1章 网络信息安全概述
  13. 用什么录屏软件能录制高清视频
  14. ruijie交换机lacp动态_vmware esxi 做链路聚合LACP踩坑
  15. 11对战平台服务器维护,11对战平台无法进入游戏【解决方法】
  16. linux中send函数MSG_NOSIGNAL
  17. 王者荣耀上官婉儿的语录
  18. 晏殊几何学导读花间流风方程定义与引理
  19. 运城学院计算机应用技术,运城学院学子在中国大学生计算机设计大赛中取得历史最好成绩...
  20. 小白入行,测试点随手记

热门文章

  1. Qt 多线程并发高阶类QtConcurrent 的使用
  2. MIUI 13:带来全新小部件,新增三大隐私保护功能等
  3. Linux删除重复内容命令uniq笔记
  4. linq.js的用法
  5. 某游戏在华为鸿蒙,华为鸿蒙系统运行安卓游戏出现新状况!安卓换皮论被彻底打脸?...
  6. linux下搭建vsftp锁定根目录,Linux服务搭建之vsftp
  7. c#form+mysql储存读取图片_C#从SQL server数据库中读取l图片和存入图片
  8. mysql换成oracle_从mysql转换到oracle数据库
  9. Java GUI 基础知识2 监听机制
  10. vista下载_Vista和视图在游戏设计中的功能