【算法修炼】直线、平面问题
一、点集合确定的不同直线数
在平面直角坐标系中,两点可以确定一条直线。如果有多点在一条直线上,那么这些点中任意两点确定的直线是同一条。
给定平面上 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值。
【算法修炼】直线、平面问题相关推荐
- 两直线平行交叉相乘_计算几何算法5. 直线、线段和平面相交(2D和3D)
直线和线段相交 平面相交 直线-平面相交 两平面相交 三个平面相交 实现 intersect2D_2Segments() inSegment() intersect3D_SegmentPlane() ...
- java 2d划线 刷子_Java图形设计中,利用Bresenham算法实现直线线型,线宽的控制(NO2DGRAPHICS)...
Java图形设计中,利用Bresenham算法实现直线线型,线宽的控制(NO2DGRAPHICS) (2007-04-05 23:37:39) Java 2D Graphics提供了强大的画线功能,可 ...
- 计算机图形学E2——OpenGL Bresenham算法画直线
其他计算机图形学实验见 链接 要求 使用Bresemham算法画直线,并且通过鼠标可以实现交互操作 参考代码: 代码1 代码2 代码3(代码好理解) 代码4(讲解很全面) #include<io ...
- EM算法在直线分类与灭点检测中的应用(关于一篇文章的读后感)
EM算法在机器学习领域有着重要的应用,其根本上要解决的问题即为是先有鸡还是先有蛋的问题:LZ最近在看EM算法在直线分类与灭点检测中的应用:翻阅了不少文献,主要参考MIT的Automatic Recov ...
- 【计算机图形学】基于OpenGL的中点Bresenham算法画直线
学习过三种画直线的方法(DDA.中点Bresenham算法.改进的中点Bresenham算法)后,想着实际操作一下如何能够实现,OpenGL无疑是很好的选择,在老师的推荐下,我尝试着用OpenGL来实 ...
- 计算机图形学直线裁剪原理,计算机图形学-3.2用Liang-Barsky算法实现直线段裁剪...
计算机图形学-3.2用Liang-Barsky算法实现直线段裁剪 计算机图形学-3.2用Liang-Barsky算法实现直线段裁剪 (1)算法设计原理 依次处理(p1,q1)(p2,q2)(p3,q3 ...
- 高中数学必修2试题:直线平面平行的判定及其性质
一. 线面平行的判定与性质 (2016·高考全国卷丙)如图,四棱锥P?ABCD中,PA⊥底面ABCD,AD∥BC,AB=AD=AC=3,PA=BC=4,M为线段AD上一点,AM=2MD,N为PC的中点 ...
- 数学基础-点到直线/平面距离
点到直线/平面的距离公式 点: 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 ...
- matlab dda算法,dda直线算法生成.pdf
dda直线算法生成 数学与计算科学学院 实 验 报 告 实验项目名称 线的生产 所属课程名称 计算机图形学 实 验 类 型 验证型 实 验 日 期 2015-4-13 班 级 信计 12-2 学 号 ...
- python使用RANSAC算法拟合直线
nptest1 = np.array(line1_yx) print("nptest1", nptest1)line1 = cv2.fitLine(nptest1, cv2.DIS ...
最新文章
- IPad开发之有帮助的开发工具
- 使用Tensoflow实现梯度下降算法的一次线性拟合
- Who is the best at Dataset X?
- office365 自定义_IT外包观察,足不出户,Office365打造教学新体验?
- python展示全部好友_python爬所有好友头像
- 选择爱人的数学方法(经典秘书问题)
- Vue JSON校验格式化编辑框 -- jsoneditor
- 20162312大二上学期总结博客
- java中使用poi导出ppt(图片和表格)
- Python OpenCv 车牌检测识别(边缘检测、HSV色彩空间判断)
- python如何将excel非首行作为dataframe的列名
- oracle awr监控报告,一个Oracle小白的AWR报告分析(一)
- 硅谷性别歧视案女高管鲍康如败诉
- 天线基本性能参数介绍
- 如何理解UART中DTE和DCE设备(模式) 这样就可以理解UART流控了
- rstudio安装后打不开_r语言和rstudio的安装
- 内存管理内幕--Jonathan Bartlett (johnnyb@eskimo.com), 技术总监, New Media Worx--
- EDIUS中视频倒放的快慢特效怎样制作
- datasource oracle,OracleDataSource连接报告异常?
- java 分部类_分部类 - Tekkaman - 博客园
热门文章
- 数据类岗位面试随想录
- 我的世界java路径错误_我的世界JAVE路径错误怎么办?路径设置方法
- Jquery面试题总结
- UI设计教程:几步教你如何创建一个漂亮又好吃的饼干
- 2023最新Java萝卜影视4.0.5系统源码+完美修复完整版
- 半年后继续捡起,,,
- AspectJ 切面注解中五种通知注解:@Before、@After、@AfterRunning、@AfterThrowing、@Around
- 计算机应用技术轻薄本,高配置轻薄笔记本推荐,终结你的选择困难症!
- win10浏览器网页打开慢
- 单反相机的照片不见了如何恢复