一、点集合确定的不同直线数

在平面直角坐标系中,两点可以确定一条直线。如果有多点在一条直线上,那么这些点中任意两点确定的直线是同一条。

给定平面上 2 × 3 个整点 {(x,y)|0 ≤ x < 2,0 ≤ y < 3, x ∈ Z,y ∈ Z},即横坐标是 0 到 1 (包含 0 和 1) 之间的整数、纵坐标是 0 到 2 (包含 0 和 2) 之间的整数的点。这些点一共确定了 11 条不同的直线。

给定平面上 20 × 21 个整点 {(x,y)|0 ≤ x < 20,0 ≤ y < 21, x ∈ Z,y ∈ Z},即横坐标是 0 到 19 (包含 0 和 19) 之间的整数、纵坐标是 0 到 20 (包含 0 和 20) 之间的整数的点。请问这些点一共确定了多少条不同的直线。

遍历两个点,采用直线方程:(y1-y2) * x +(x2-x1) * y +( x1 * y2 - x2 * y1)=0直线方程,最好采用这种方式,可以避免精度问题、分数问题,注意要求三个数的gcd,并约分,如果求直线条数可以直接装到set中。

上面的直线方程由两点式直线方程推出,即 (y - y2) / (y1 - y2) = (x - x2) / (x1 - x2)

二、直线上最多的点数



思路,遍历两个点,统计从每个点出发的k(斜率)的个数,只取出现次数最多的k,个数+1就 = 对当前点来说,一条直线最多能够经过的点的个数(这条直线一定包含当前点,这就是前面+1的原因),再从剩下的点出发,依次比较答案,取最大值即可。

class Solution {public int maxPoints(int[][] points) {int ans = 0;for (int i = 0; i < points.length; i++) {HashMap<String, Integer> map = new HashMap<>();// 对于当前点来说,一条直线最多经过的点的个数int max = 0;for (int j = i + 1; j < points.length; j++) {int x1 = points[i][0], y1 = points[i][1];int x2 = points[j][0], y2 = points[j][1];int up = y2 - y1;int down = x2 - x1;int tmp = gcd(up, down);up /= tmp;down /= tmp;String str = up + "_" + down;map.put(str, map.getOrDefault(str, 0) + 1);max = Math.max(max, map.get(str));}// 别忘了自己本身也算一个点ans = Math.max(ans, max + 1);}return ans;}public int gcd(int a, int b) {if (b == 0) return a;return gcd(b, a % b);}
}

三、平面切分

【问题描述】
平面上有 N 条直线,其中第 i 条直线是 y = Ai · x + Bi。
请计算这些直线将平面分成了几个部分。
【输入格式】
第一行包含一个整数 N。
以下 N 行,每行包含两个整数 Ai; Bi。
【输出格式】
一个整数代表答案。
【样例输入】
3
1 1
2 2
3 3
1
2
3
4
【样例输出】
6
1
【评测用例规模与约定】
对于 50% 的评测用例, 1 ≤ N ≤ 4, −10 ≤ Ai; Bi ≤ 10。
对于所有评测用例, 1 ≤ N ≤ 1000, −100000 ≤ Ai; Bi ≤ 100000。

平面中只有一条直线时(划分两个平面),如果增加一条平行的直线,划分的平面数 + 1;如果增加的一条直线是相交的,划分的平面数 + 2 = 4。再增加一条线与之前两条线相交,平面数 + 3 = 7。
规律:每增加一条直线,增加的平面数 = 该直线与之前直线的交点数 + 1

需要注意的是,可能有重复边的情况,要去重,这里选择直接对坐标点去重,更加方便。

题目中直接告诉了斜率和截距,那就很方便,不用再求k了。

y = A1X + B1,y = A2X + B2,交点,x = (B2 - B1) / (A1 - A2),y = A1X + B1或者y = A2X + B2都可以。

四、消灭老鼠


用(y1-y2) * x +(x2-x1) * y +( x1 * y2 - x2 * y1)=0直线方程来表示,找不同直线的条数,注意去重,注意使用gcd对三数约分。

import java.util.HashSet;
import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner scan = new Scanner(System.in);int n = scan.nextInt();// 激光枪所在位置int x2 = scan.nextInt();int y2 = scan.nextInt();int[] mouses = new int[n];// 计算当前点与与激光枪形成直线,求直线条数即可(去重)HashSet<String> set = new HashSet<>();// (y1 - y2) * x + (x2 - x1) * y + (x1 * y2 - x2 * y1) = 0for (int i = 0; i < n; i++) {int x1 = scan.nextInt();int y1 = scan.nextInt();int a = y1 - y2;int b = x2 - x1;int c = x1 * y2 - x2 * y1;// 三数约分int div = gcd(a, gcd(b, c));a /= div;b /= div;c /= div;String tmp = a + "x" + "+" + b + "y" + "+" + c;set.add(tmp);}System.out.println(set.size());}public static int gcd(int a, int b) {return b == 0 ? a : gcd(b, a % b);}
}

如果题目中要求站在原点,遍历不同的方向,那就需要把四个象限的k值分开考虑,此时最好的方法时, 求gcd时,都使用绝对值,这样得到的最大公约数都是正数,可以分别为每个象限记录k值。

【算法修炼】直线、平面问题相关推荐

  1. 两直线平行交叉相乘_计算几何算法5. 直线、线段和平面相交(2D和3D)

    直线和线段相交 平面相交 直线-平面相交 两平面相交 三个平面相交 实现 intersect2D_2Segments() inSegment() intersect3D_SegmentPlane() ...

  2. java 2d划线 刷子_Java图形设计中,利用Bresenham算法实现直线线型,线宽的控制(NO2DGRAPHICS)...

    Java图形设计中,利用Bresenham算法实现直线线型,线宽的控制(NO2DGRAPHICS) (2007-04-05 23:37:39) Java 2D Graphics提供了强大的画线功能,可 ...

  3. 计算机图形学E2——OpenGL Bresenham算法画直线

    其他计算机图形学实验见 链接 要求 使用Bresemham算法画直线,并且通过鼠标可以实现交互操作 参考代码: 代码1 代码2 代码3(代码好理解) 代码4(讲解很全面) #include<io ...

  4. EM算法在直线分类与灭点检测中的应用(关于一篇文章的读后感)

    EM算法在机器学习领域有着重要的应用,其根本上要解决的问题即为是先有鸡还是先有蛋的问题:LZ最近在看EM算法在直线分类与灭点检测中的应用:翻阅了不少文献,主要参考MIT的Automatic Recov ...

  5. 【计算机图形学】基于OpenGL的中点Bresenham算法画直线

    学习过三种画直线的方法(DDA.中点Bresenham算法.改进的中点Bresenham算法)后,想着实际操作一下如何能够实现,OpenGL无疑是很好的选择,在老师的推荐下,我尝试着用OpenGL来实 ...

  6. 计算机图形学直线裁剪原理,计算机图形学-3.2用Liang-Barsky算法实现直线段裁剪...

    计算机图形学-3.2用Liang-Barsky算法实现直线段裁剪 计算机图形学-3.2用Liang-Barsky算法实现直线段裁剪 (1)算法设计原理 依次处理(p1,q1)(p2,q2)(p3,q3 ...

  7. 高中数学必修2试题:直线平面平行的判定及其性质

    一. 线面平行的判定与性质 (2016·高考全国卷丙)如图,四棱锥P?ABCD中,PA⊥底面ABCD,AD∥BC,AB=AD=AC=3,PA=BC=4,M为线段AD上一点,AM=2MD,N为PC的中点 ...

  8. 数学基础-点到直线/平面距离

    点到直线/平面的距离公式 点: p ( x 0 , y 0 ) p(x_0,y_0) p(x0​,y0​) 平面: f ( x , y ) = A x + B y + C f(x,y)=Ax+By+C ...

  9. matlab dda算法,dda直线算法生成.pdf

    dda直线算法生成 数学与计算科学学院 实 验 报 告 实验项目名称 线的生产 所属课程名称 计算机图形学 实 验 类 型 验证型 实 验 日 期 2015-4-13 班 级 信计 12-2 学 号 ...

  10. python使用RANSAC算法拟合直线

    nptest1 = np.array(line1_yx) print("nptest1", nptest1)line1 = cv2.fitLine(nptest1, cv2.DIS ...

最新文章

  1. IPad开发之有帮助的开发工具
  2. 使用Tensoflow实现梯度下降算法的一次线性拟合
  3. Who is the best at Dataset X?
  4. office365 自定义_IT外包观察,足不出户,Office365打造教学新体验?
  5. python展示全部好友_python爬所有好友头像
  6. 选择爱人的数学方法(经典秘书问题)
  7. Vue JSON校验格式化编辑框 -- jsoneditor
  8. 20162312大二上学期总结博客
  9. java中使用poi导出ppt(图片和表格)
  10. Python OpenCv 车牌检测识别(边缘检测、HSV色彩空间判断)
  11. python如何将excel非首行作为dataframe的列名
  12. oracle awr监控报告,一个Oracle小白的AWR报告分析(一)
  13. 硅谷性别歧视案女高管鲍康如败诉
  14. 天线基本性能参数介绍
  15. 如何理解UART中DTE和DCE设备(模式) 这样就可以理解UART流控了
  16. rstudio安装后打不开_r语言和rstudio的安装
  17. 内存管理内幕--Jonathan Bartlett (johnnyb@eskimo.com), 技术总监, New Media Worx--
  18. EDIUS中视频倒放的快慢特效怎样制作
  19. datasource oracle,OracleDataSource连接报告异常?
  20. java 分部类_分部类 - Tekkaman - 博客园

热门文章

  1. 数据类岗位面试随想录
  2. 我的世界java路径错误_我的世界JAVE路径错误怎么办?路径设置方法
  3. Jquery面试题总结
  4. UI设计教程:几步教你如何创建一个漂亮又好吃的饼干
  5. 2023最新Java萝卜影视4.0.5系统源码+完美修复完整版
  6. 半年后继续捡起,,,
  7. AspectJ 切面注解中五种通知注解:@Before、@After、@AfterRunning、@AfterThrowing、@Around
  8. 计算机应用技术轻薄本,高配置轻薄笔记本推荐,终结你的选择困难症!
  9. win10浏览器网页打开慢
  10. 单反相机的照片不见了如何恢复