2014-03-20 02:24

题目:给定二位平面上一堆点,找到一条直线,使其穿过的点数量最多。

解法:我的解法只能适用整点,对于实数坐标就得换效率更低的办法了。请参见LeetCode - Max Points on a Line - zhuli19901106 - 博客园

代码:

 // 7.6 Find the line that crosses the most points.
#include <unordered_map>
#include <vector>
using namespace std; struct Point {
int x;
int y;
Point() : x(), y() {}
Point(int a, int b) : x(a), y(b) {}
}; struct st {
int x;
int y;
st(int _x = , int _y = ): x(_x), y(_y) {}; bool operator == (const st &other) const {
return x == other.x && y == other.y;
}; bool operator != (const st &other) const {
return x != other.x || y != other.y;
};
}; struct line {
// ax + by + c = 0;
int a;
int b;
int c;
line(int _a = , int _b = , int _c = ): a(_a), b(_b), c(_c) {};
}; struct hash_functor {
size_t operator () (const st &a) const {
return (a.x * + a.y);
}
}; struct compare_functor {
bool operator () (const st &a, const st &b) const {
return (a.x == b.x && a.y == b.y);
}
}; typedef unordered_map<st, int, hash_functor, compare_functor> st_map; class Solution {
public:
int maxPoints(vector<Point> &points, line &result_line) {
int n = (int)points.size(); if (n <= ) {
return n;
} st_map um;
st tmp;
// special tangent value for duplicate points
st dup(, ); int i, j;
st_map::const_iterator umit;
int dup_count;
int max_count;
int result = ;
for (i = ; i < n; ++i) {
for (j = i + ; j < n; ++j) {
tmp.x = points[j].x - points[i].x;
tmp.y = points[j].y - points[i].y;
// make sure one tangent value has one representation only.
normalize(tmp);
if (um.find(tmp) != um.end()) {
++um[tmp];
} else {
um[tmp] = ;
}
}
max_count = dup_count = ;
for (umit = um.begin(); umit != um.end(); ++umit) {
if (umit->first != dup) {
if (umit->second > max_count) {
max_count = umit->second;
getLine(umit->first, points[i], result_line);
}
} else {
dup_count = umit->second;
}
}
max_count = max_count + dup_count + ;
result = (max_count > result ? max_count : result);
um.clear();
} return result;
}
private:
void normalize(st &tmp) {
if (tmp.x == && tmp.y == ) {
// (0, 0)
return;
}
if (tmp.x == ) {
// (0, 1)
tmp.y = ;
return;
}
if (tmp.y == ) {
// (1, 0)
tmp.x = ;
return;
}
if (tmp.x < ) {
// (-2, 3) and (2, -3) => (2, -3)
tmp.x = -tmp.x;
tmp.y = -tmp.y;
} int gcd_value; gcd_value = (tmp.y > ? gcd(tmp.x, tmp.y) : gcd(tmp.x, -tmp.y));
// (4, -6) and (-30, 45) => (2, -3)
// using a double precision risks in accuracy
// so I did it with a pair
tmp.x /= gcd_value;
tmp.y /= gcd_value;
} int gcd(int x, int y) {
// used for reduction of fraction
return y ? gcd(y, x % y) : x;
} void getLine(st tan, Point p, line &res) {
res.a = tan.y;
res.b = -tan.x;
res.c = -(res.a * p.x + res.b * p.y);
}
}; int main()
{
vector<Point> v;
Solution sol;
int i, n;
Point p;
line res; while (scanf("%d", &n) == ) {
for (i = ; i < n; ++i) {
scanf("%d%d", &p.x, &p.y);
v.push_back(p);
}
sol.maxPoints(v, res);
printf("%d %d %d\n", res.a, res.b, res.c);
v.clear();
} return ;
}

《Cracking the Coding Interview》——第7章:数学和概率论——题目6的更多相关文章

  1. Cracking the coding interview 第一章问题及解答

    Cracking the coding interview 第一章问题及解答 不管是不是要挪地方,面试题具有很好的联系代码总用,参加新工作的半年里,做的大多是探索性的工作,反而代码写得少了,不高兴,最 ...

  2. 《Cracking the Coding Interview》读书笔记

    <Cracking the Coding Interview>是适合硅谷技术面试的一本面试指南,因为题目分类清晰,风格比较靠谱,所以广受推崇. 以下是我的读书笔记,基本都是每章的课后习题解 ...

  3. Cracking the coding interview

    写在开头 最近忙于论文的开题等工作,还有阿里的实习笔试,被虐的还行,说还行是因为自己的水平或者说是自己准备的还没有达到他们所需要人才的水平,所以就想找一本面试的书<Cracking the co ...

  4. Cracking the coding interview目录及资料收集

    前言 <Cracking the coding interview>是一本被许多人极力推荐的程序员面试书籍, 详情可见:http://www.careercup.com/book. 第六版 ...

  5. Cracking the Coding Interview(Trees and Graphs)

    Cracking the Coding Interview(Trees and Graphs) 树和图的训练平时相对很少,还是要加强训练一些树和图的基础算法.自己对树节点的设计应该不是很合理,多多少少 ...

  6. Cracking the Coding Interview(Stacks and Queues)

    Cracking the Coding Interview(Stacks and Queues) 1.Describe how you could use a single array to impl ...

  7. 《Cracking the Coding Interview》——第7章:数学和概率论——题目7

    2014-03-20 02:29 题目:将质因数只有3, 5, 7的正整数从小到大排列,找出其中第K个. 解法:用三个iterator指向3, 5, 7,每次将对应位置的数分别乘以3, 5, 7,取三 ...

  8. 《Cracking the Coding Interview》——第7章:数学和概率论——题目5

    2014-03-20 02:20 题目:给定二维平面上两个正方形,用一条直线将俩方块划分成面积相等的两部分. 解法:穿过对称中心的线会将面积等分,所以连接两个中心即可.如果两个中心恰好重合,那么任意穿 ...

  9. 《Cracking the Coding Interview》——第7章:数学和概率论——题目4

    2014-03-20 02:16 题目:只用加法和赋值,实现减法.乘法.除法. 解法:我只实现了整数范围内的.减法就是加上相反数.乘法就是连着加上很多个.除法就是减到不能减为止,数数总共减了多少个. ...

随机推荐

  1. 搭建vs2010 boost开发环境

    一.编译boost库 第一步:下载boost库,下载地址http://sourceforge.net/projects/boost/files/boost/1.55.0/ 第二部:解压boost库,例 ...

  2. hdu-2609 How many---最小表示法模板+set判重

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2609 题目大意: 有n个有01组成的字符串,每个字符串都代表一个项链,那么该字符串就是一个环状的结构 ...

  3. Treap 实现名次树

    在主流STL版本中,set,map,都是BST实现的,具体来说是一种称为红黑树的动态平衡BST: 但是在竞赛中并不常用,因为红黑树过于复杂,他的插入 5 种,删除 6 中,代码量极大(如果你要改板子的 ...

  4. Shiro Demo:SpringBoot+Shiro+Druid+MyBatis

    访问start.spring.io生成项目: 然后选择依赖: pom.xml: <?xml version="1.0" encoding="UTF-8"? ...

  5. python中的for循环如何控制步长

    for i in range(开始/左边界, 结束/右边界, 步长): print i 例如 for i in range(1, 10, 2): print i 等价于 for (i=1;i<= ...

  6. OpenACC例子

    timeinfo1.c代码 #include<stdio.h> #define N 100 int main() { int A[N]; #pragma acc kernels { ; i ...

  7. vs2012或vs2013调试卡 关闭调试卡

    以前vs2013就有这个问题.没有解决.今天又装了vs2012.又遇到了.特别郁闷. 今天一定要解决.网上百度了.很久.可能关键字有问题.没有找到好的办法. 找到的办法有.显卡问题.不是管理员运行问题 ...

  8. 【例题收藏】◇例题·I◇ Snuke's Subway Trip

    ◇例题·I◇ Snuke's Subway Trip 题目来源:Atcoder Regular 061 E题(beta版) +传送门+ 一.解析 (1)最短路实现 由于在同一家公司的铁路上移动是不花费 ...

  9. datatable设置动态宽度,超过一定长度出现滚动条

    获得宽度:var tableAutoWidth = $('.dataTable_wrapper').width();if (tableAutoWidth < 1200) { tableAutoW ...

  10. 想学习一下node.js,重新安装配置了node

    根据这个网站上的教程安装配置的,还不错一次就成功了.觉得安装没什么,就是配置路径的时候容易错. http://www.runoob.com/nodejs/nodejs-install-setup.ht ...