Description

牛客网 2018校招真题 直线上的点

Solving Ideas

https://leetcode.com/problems/max-points-on-a-line/

https://leetcode.com/problems/max-points-on-a-line/discuss/47113/A-java-solution-with-notes

https://www.jianshu.com/p/317c676f9e00

基本思路:
因为两点确定一条直线,所以可以遍历所有直线,并在遍历的过程中,把已遍历的直线缓存起来,当遇到的相同直线时,就把这条直线上存在的点的个数累加,这样就可以求得经过某个点的某条直线上最多的点的个数。

如何遍历所有的直线?
两层循环遍历所有直线。假设有数组Point[] points,则

for (int i = 0; i < points.length; i++) {...for (int j = i + 1; j < points.length; j++) {...}...
}

外层循环:表示遍历经过points[i]这个点的所有可能的直线
内层循环:表示由points[i]points[j]这两点确定的直线
因为由(points[i], points[j])确定的直线 与 由(points[j], points[i])确定的直线是相同,和两点的顺序无关,为了避免重复计算,所以内层循环将j初始化为i + 1

如何判断直线是否相同?
对于二维的情况,如果两条直线斜率相等且都通过某一个定点,那么可以判定这两条直线相等。
例如平面内有点A、B、C,直线AB的斜率为k1,直线AC的斜率为k2,因为k1=k2且两直线都通过点A,所以AB和AC是一条直线,即A、B、C三点共线。

对于三维的情况,同样可以采用类似的方法来进行判定,只不过空间中用的是向量描述而不是斜率。
对于空间中两点A(x1,y1,z1)A(x_1, y_1, z_1)A(x1​,y1​,z1​)和B(x2,y2,z2)B(x_2, y_2, z_2)B(x2​,y2​,z2​),则AB的方向向量为(x2−x1,y2−y1,z2−z1)(x_2-x_1, y_2-y_1, z_2-z_1)(x2​−x1​,y2​−y1​,z2​−z1​),由两点式可得AB直线方程为:
x−x1x2−x1=y−y1y2−y1=z−z1z2−z1\frac{x-x_1}{x_2-x_1}=\frac{y-y_1}{y_2-y_1}=\frac{z-z_1}{z_2-z_1}x2​−x1​x−x1​​=y2​−y1​y−y1​​=z2​−z1​z−z1​​

对于点A(x1,y1,z1)A(x_1, y_1, z_1)A(x1​,y1​,z1​)和C(x3,y3,z3)C(x_3, y_3, z_3)C(x3​,y3​,z3​),则AC的方向向量为(x3−x1,y3−y1,z3−z1)(x_3-x_1, y_3-y_1, z_3-z_1)(x3​−x1​,y3​−y1​,z3​−z1​),AC直线方程为:
x−x1x3−x1=y−y1y3−y1=z−z1z3−z1\frac{x-x_1}{x_3-x_1}=\frac{y-y_1}{y_3-y_1}=\frac{z-z_1}{z_3-z_1}x3​−x1​x−x1​​=y3​−y1​y−y1​​=z3​−z1​z−z1​​

当AB的方向向量(x2−x1,y2−y1,z2−z1)(x_2-x_1, y_2-y_1, z_2-z_1)(x2​−x1​,y2​−y1​,z2​−z1​)与AC的方向向量(x3−x1,y3−y1,z3−z1)(x_3-x_1, y_3-y_1, z_3-z_1)(x3​−x1​,y3​−y1​,z3​−z1​)平行时,AB、AC共线,此时两条直线方程是相等的。

简单来说,对于空间中的两条直线,如果方向向量平行,且都通过某一个定点,即方向向量共线时,则可以判定这两条直线相等。

特殊情况处理:
遍历时,外层循环的点当做定点,当内层循环的点与该定点重叠时,则将其累加到该定点确定的所有直线的点数上。

Solution

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;class Point {int x;int y;int z;Point(int x, int y, int z) {this.x = x;this.y = y;this.z = z;}
}/*** @author wylu*/
public class Main {public static void main(String[] args) throws IOException {BufferedReader br = new BufferedReader(new InputStreamReader(System.in));int n = Integer.parseInt(br.readLine());Point[] points = new Point[n];for (int i = 0; i < n; i++) {String[] strs = br.readLine().split(" ");points[i] = new Point(Integer.parseInt(strs[0]), Integer.parseInt(strs[1]), Integer.parseInt(strs[2]));}System.out.println(maxPoints(points));}private static int maxPoints(Point[] points) {if (points.length <= 2) return points.length;Map<Integer, Map<Integer, Map <Integer, Integer>>> map = new HashMap<>();int res = 0;for (int i = 0; i < points.length; i++) {int overlap = 0, count = 0;for (int j = i + 1; j < points.length; j++) {//此处不取绝对值是因为下方通过约分可以保证其转为正整数int dx = points[i].x - points[j].x;int dy = points[i].y - points[j].y;int dz = points[i].z - points[j].z;if (dx == 0 && dy == 0 && dz == 0) {overlap++;continue;}// (2,2,2)与(1,1,1)平行,在这里因为都通过points[i],所以(2,2,2)与(1,1,1)共线int gcd = gcd(dx, dy, dz);dx /= gcd;dy /= gcd;dz /= gcd;if (map.containsKey(dx)) {if (map.get(dx).containsKey(dy)) {if (map.get(dx).get(dy).containsKey(dz)) {map.get(dx).get(dy).put(dz, map.get(dx).get(dy).get(dz) + 1);} else {map.get(dx).get(dy).put(dz, 1);}} else {Map<Integer, Integer> m = new HashMap<>();m.put(dz, 1);map.get(dx).put(dy, m);}} else {Map<Integer, Integer> m1 = new HashMap<>();m1.put(dz, 1);Map<Integer, Map<Integer, Integer>> m2 = new HashMap<>();m2.put(dy, m1);map.put(dx, m2);}count = Math.max(count, map.get(dx).get(dy).get(dz));}res = Math.max(res, count + 1 + overlap);//如果下一个定点的直线的方向向量与当前定点的直线的方向向量平行时,//内层循环将会判定这两个方向向量共线,但实际上有可能并不共线,所以必须清除缓存map.clear();}return res;}private static int gcd(int a, int b, int c) {return gcd(a, gcd(b, c));}private static int gcd(int a, int b) {return b == 0 ? a : gcd(b, a % b);}
}

牛客网 2018校招真题 吉比特 直线上的点相关推荐

  1. 牛客网 2018校招真题 美团点评 K的倍数

    Description 牛客网 2018校招真题 K的倍数 Solving Ideas sum[i + 1]: 表示序列p[0]...p[i]的和 从长度最大的子串开始判断,当剩余需要判断子串长度不可 ...

  2. 牛客网 2018校招真题 摩拜 排序次数

    Description 牛客网 2018校招真题 排序次数 Solving Ideas 将数组a的元素拷贝到数组b 对数组b进行排序 对比数组b,统计数组a中已排序的元素个数 如:a = [2, 11 ...

  3. 牛客网 2018校招真题 滴滴出行 寻找丑数

    Description 牛客网 2018校招真题 寻找丑数 Solving Ideas 参考<剑指offer>丑数 Time complexity : O(n)O(n)O(n) Space ...

  4. 牛客网 2018校招真题 爱奇艺 最后一位

    Description 牛客网 2018校招真题 最后一位 Solving Ideas 二分查找 Solution import java.io.BufferedReader; import java ...

  5. 牛客网 2018校招真题 京东 回文

    Description 牛客网 2018校招真题 回文 Solving Ideas 计算以str[str.length() - 1]为结尾的最大的回文长度,从而判断最少需要追加多少个字母才能使整个串成 ...

  6. 牛客网 2018校招真题 美团点评 关灯游戏

    Description 牛客网 2018校招真题 关灯游戏 Solving Ideas 只与最右边的数字有关,如果最右边的数字为1,则Alice赢,否则Bob赢 假设最右边的数字为1 因为Alice是 ...

  7. 牛客网 2018校招真题 网易 骰子游戏

    Description 牛客网 2018校招真题 骰子游戏 Solving Ideas 参考<剑指offer>n个骰子的点数 考虑用两个数组来存储骰子点数的每一个总数出现的次数. 在一次循 ...

  8. 牛客网 2018校招真题 美团点评 重要节点

    Description 牛客网 2018校招真题 重要节点 Solving Ideas BFS 创建一个标记数组arrive,arrive[i][j]为true表示从i可以到达j, false则不能 ...

  9. 牛客网 2018校招真题 招商银行信用卡 整数成绩最大化

    Description 牛客网 2018校招真题 整数成绩最大化 Solving Ideas 当n>4时,最大受益为尽可能拆分出更多的数字3,最后一个不足3的,若其为1则分给其中一个3,得到4, ...

  10. 牛客网——2017校招真题在线编程(pythonC++)

    牛客网--2017校招真题在线编程(python&C++) 1.n个数里的最小k个 题目描述 找出n个数里最小的k个 输入描述: 每个测试输入包含空格分割的n+1个整数,最后一个整数为k值,n ...

最新文章

  1. 宁波大红鹰学院计算机科学与技术,2019宁波大红鹰学院专业排名
  2. vs下.def文件使用无效问题
  3. 去除下拉框的默认样式
  4. Codeforces Round #409 (Div. 2)
  5. mysql undrop_MySQL 如何对InnoDB使用Undrop来恢复InnoDB数据
  6. Java实训项目9:GUI学生信息管理系统 - 实现步骤 - 创建数据访问接口
  7. 关于Element UI中select组件中遇到的问题
  8. zbb20171215 bootstrap 日期控件.rar
  9. tkinter的可视化拖拽工具_微信小游戏内测可视化工具!“人人都是小程序开发者”的时代到了...
  10. 蓝桥杯2015年第六届C/C++B组第六题-加法变乘法
  11. linux使用脚本执行vim命令行,linux – 如何通过shell脚本执行vim命令
  12. 免费主机 虚拟主机 香港虚拟主机
  13. Oracle等数据库报盘步骤(使用脚本批量压缩)
  14. 汇编-ARMv8架构指令集
  15. 牛客寒假基础集训营 | Day1 D题—hanayo和米饭
  16. 解决spark运行时控制台打印冗杂的INFO(屏蔽掉无用的INFO)
  17. 透过事物看本质的能力怎么培养?
  18. Flutter3引用原生播放器-Android篇
  19. 如何使QGraphicsItem不随QGraphicsView放大缩小而改变大小
  20. 【嵌入式开发教程8】手把手教你做平板电脑-Camera 驱动实验教程

热门文章

  1. unix和linux发音,Linux术语发音大全
  2. 2.jQuery常见API
  3. Java多线程系列--“JUC集合”02之 CopyOnWriteArrayList
  4. Android仿人人客户端(v5.7.1)——新鲜事之分享照片
  5. 百度翻译使用经验(Python版)
  6. ubuntu和kubuntu换源
  7. 运动目标跟踪(十一)--CN及CSK跟踪原理
  8. Cpp调用C中的函数
  9. 论文理解【Offline RL】 —— 【COIL】Curriculum Offline Imitating Learning
  10. 2021年美赛准备大全