蓝桥杯算法训练-共线

本文探讨了在二维平面上寻找最多共线点数量的问题。通过遍历所有点对,利用哈希表统计斜率相同的直线上的点数,最终找到最多共线点的数量。提供了一种O(n²logn²)的时间复杂度解决方案。

个人博客
算法训练题解

题目描述

问题描述
  给定2维平面上n个整点的坐标,一条直线最多能过几个点?
输入格式
  第一行一个整数n表示点的个数
  以下n行,每行2个整数分别表示每个点的x,y坐标。
输出格式
  输出一个整数表示答案。
样例输入
5
0 0
1 1
2 2
0 3
2 3

样例输出
3

题目解释

  1. 题目数据量很小支持 O ( n 2 l o g n 2 ) O(n^2logn^2) O(n2logn2)的时间复杂度。
  2. 共线,也就是斜率相同,并且有公共点。

针对上面可以采用暴力的做法:遍历公共点,对于每一个公共点,求斜率相同的直线,最多有多少个,斜率相同的直线可以采用hash表进行统计,斜率作为key, value就是点的个数。初始点的个数应该是1,因为公共点需要算进去。

当然,也可以遍历斜率,把斜率相同的划分成一个集合,然后使用并查集。点的坐标作为点的id,初始父节点为线的一端,如果共线,那么合并。这个时间复杂度是 O ( n 4 l o g n ) O(n^4logn) O(n4logn)

代码


import java.util.HashMap;
import java.util.Scanner;

/**
 * @author: Zekun Fu
 * @date: 2022/11/2 10:04
 * @Description: 共线
 */


public class Main {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        double[] a = new double[n];
        double[] b = new double[n];
        for (int i = 0; i < n; i++) {
            a[i] = sc.nextDouble();
            b[i] = sc.nextDouble();
        }
        int ans = 0;
        for (int i = 0; i < n; i++) {
            HashMap<Double, Integer>cnt = new HashMap<>();
            for (int j = i + 1; j < n; j++) {
                double k;
                if (a[i] == a[j]) k = Double.MAX_VALUE;
                else k = (b[i] - b[j]) / (a[i] - a[j]);
                cnt.put(k, cnt.getOrDefault(k, 1) + 1);
                ans = Math.max(ans, cnt.get(k));
            }
        }
        System.out.println(ans);
    }
}

评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值