【九度】题目1548:平面上的点 && 【LeetCode】Max Points on a Line

时间:2021-02-06 09:28:09

1、Jobdu 题目1548:平面上的点 

题目描述:

         给定平面上的n个点,任意做一条直线,求至多能有几个点恰好落在直线上。
输入:
        包含多组测试数据,每组测试数据由一个整数n(0<=n<=100)开始,代表平面上点的个数。
        接下去n行每行给出一个点的坐标(x,y),x、y的绝对值均小于等于100。
输出:
        对于每组测试数据,输出一个整数,表示至多能有几个点恰好落在直线上。
样例输入:
        2
        0 0
        1 1
        4
        0 0
        1 1
        2 2 
        3 6
样例输出:
        2
        3
来源:
       2014年王道论坛研究生机试练习赛(一)
2、 Max Points on a Line
        Total Accepted: 5322 Total Submissions: 52469 My Submissions
        Given n points on a 2D plane, find the maximum number of points that lie on the same straight line.
        这两道题目一样。本来想着,这个题应该不止考察三重循环吧,总觉得会超时,后来也想不出太好的办法,就干脆暴力了。
        因为两点成一直线,公式为(y - y1)/(y2 - y1) = (x - x1)/(x2 - x1)。两点成一直线以后,判断第3个点是否在该直线上。这里注意,因为有可能有重复的点,如果y1 == y2 && x1 == x2,那么形成直线的时候,其实已经有3个点了。
        其实对于Java来说,应该还有其他处理的办法,就是统计重复字符的次数,然后在统计直线上点的个数。C++也有map,不过我不太熟,给出Java的第二种处理办法吧。九度这个方法比1慢了将近一半时间,LeetCode居然快了10ms。

1、Java AC 方法1

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;

public class Main {
/*
* 1548
*/
public static void main(String[] args) throws IOException {
StreamTokenizer st = new StreamTokenizer(new BufferedReader(
new InputStreamReader(System.in)));
while (st.nextToken() != StreamTokenizer.TT_EOF) {
int n = (int)st.nval;
if (n == 0) {
System.out.println(n);
continue;
}
Node nodes[] = new Node[n];
for (int i = 0; i < n; i++) {
st.nextToken();
int x = (int)st.nval;
st.nextToken();
int y = (int)st.nval;
nodes[i] = new Node(x, y);
}
if (n == 1 || n == 2) {
System.out.println(n);
continue;
}
int maxNum = 0;
for (int i = 0; i < n; i++) {
int x1 = nodes[i].x;
int y1 = nodes[i].y;
for (int j = i+1; j < n; j++) {
int x2 = nodes[j].x;
int y2 = nodes[j].y;
int tempNum = 2;
if (x2 == x1 && y2 == y1) {
tempNum = 3;
j++;
}
if (j >= n) {
maxNum = Math.max(tempNum, maxNum);
continue;
}
x2 = nodes[j].x;
y2 = nodes[j].y;
for (int k = 0; k < n; k++) {
if (k >= i && k <= j) {
continue;
}
int x3 = nodes[k].x;
int y3 = nodes[k].y;
int num1 = (y3 - y1)*(x2 - x1);
int num2 = (y2 - y1)*(x3 - x1);
if (num1 == num2) {
tempNum++;
}
}
maxNum = Math.max(tempNum, maxNum);
}
}
System.out.println(maxNum);
}
}
public static class Node{
int x;
int y;
Node(int x, int y){
this.x = x;
this.y = y;
}
}
}
/**************************************************************
Problem: 1548
User: wangzhenqing
Language: Java
Result: Accepted
Time:490 ms
Memory:17044 kb
****************************************************************/
1、C++ AC
#include <stdio.h>const int maxn = 102;struct Node{    int x;    int y;};int n, i;Node nodes[maxn];   int max(int a, int b){    return a > b ? a : b;}int main(){    while(scanf("%d",&n) != EOF){        for(i = 0; i < n; i++){            scanf("%d %d",&nodes[i].x,&nodes[i].y);        }        if(n == 0 || n == 1 || n == 2){            printf("%d\n",n);            continue;        }        int maxNum = 0;        for(i = 0; i < n; i++){            for(int j = i+1; j < n; j++){                int tempNum = 2;                while (j < n && nodes[j].x == nodes[i].x && nodes[j].y == nodes[i].y) {                    tempNum++;                    j++;                }                if(j == n){                    tempNum--;                }                for (int k = 0; k < n; k++) {                    if (k >= i && k <= j) {                        continue;                    }                    int num1 = (nodes[k].y - nodes[i].y)*(nodes[j].x - nodes[i].x);                    int num2 = (nodes[j].y - nodes[i].y)*(nodes[k].x - nodes[i].x);                    if (num1 == num2) {                        tempNum++;                    }                }                maxNum = max(tempNum, maxNum);            }        }        printf("%d\n",maxNum);    }    return 0;}  /**************************************************************    Problem: 1548    User: wangzhenqing    Language: C++    Result: Accepted    Time:40 ms    Memory:1020 kb****************************************************************/
1、Java AC 方法2  

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
import java.util.HashMap;
import java.util.Map;

public class Main {
/*
* 1548
*/
public static void main(String[] args) throws IOException {
StreamTokenizer st = new StreamTokenizer(new BufferedReader(
new InputStreamReader(System.in)));
while (st.nextToken() != StreamTokenizer.TT_EOF) {
int n = (int)st.nval;
if (n == 0) {
System.out.println(n);
continue;
}
Node nodes[] = new Node[n];
Map<String, Integer> numMap = new HashMap<String, Integer>();
int k = 0;
for (int i = 0; i < n; i++) {
st.nextToken();
int x = (int)st.nval;
st.nextToken();
int y = (int)st.nval;
String xy = x + "_" + y;
int num = 1;
if (numMap.containsKey(xy)) {
num += numMap.get(xy);
}else {
nodes[k] = new Node(x, y);
k++;
}
numMap.put(xy, num);
}
if (n == 1 || n == 2) {
System.out.println(n);
continue;
}
n = k;
int maxNum = 0;
for(int i = 0; i < n; i++){
for(int j = i+1; j < n; j++){
int tempNum = 0;
tempNum += numMap.get(nodes[i].x + "_" + nodes[i].y)
+ numMap.get(nodes[j].x + "_" + nodes[j].y);
for (k = j+1; k < n; k++) {
int num1 = (nodes[k].y - nodes[i].y)*
(nodes[j].x - nodes[i].x);
int num2 = (nodes[j].y - nodes[i].y)*
(nodes[k].x - nodes[i].x);
if (num1 == num2) {
tempNum += numMap.get
(nodes[k].x + "_" + nodes[k].y);
}
}
maxNum = Math.max(tempNum, maxNum);
}
}
for ( int value : numMap.values()) {
maxNum = Math.max(value, maxNum);
}
System.out.println(maxNum);
}
}
public static class Node{
int x;
int y;
Node(int x, int y){
this.x = x;
this.y = y;
}
}
}

/**************************************************************
Problem: 1548
User: wangzhenqing
Language: Java
Result: Accepted
Time:820 ms
Memory:35804 kb
****************************************************************/
2、Java AC 方法1

/**
* Definition for a point.
* class Point {
* int x;
* int y;
* Point() { x = 0; y = 0; }
* Point(int a, int b) { x = a; y = b; }
* }
*/
public class Solution {
public int maxPoints(Point[] points) {
if(points == null || points.length == 0){
return 0;
}
int n = points.length;
if(n == 1 || n == 2){
return n;
}
int maxNum = 0;
for(int i = 0; i < n; i++){
for(int j = i+1; j < n; j++){
int tempNum = 2;
while (j < n && points[j].x == points[i].x
&& points[j].y == points[i].y) {
tempNum++;
j++;
}
if(j == n){
tempNum--;
maxNum = Math.max(tempNum, maxNum);
continue;
}
for (int k = 0; k < n; k++) {
if (k >= i && k <= j) {
continue;
}
int num1 = (points[k].y - points[i].y)*
(points[j].x - points[i].x);
int num2 = (points[j].y - points[i].y)*
(points[k].x - points[i].x);
if (num1 == num2) {
tempNum++;
}
}
maxNum = Math.max(tempNum, maxNum);
}
}
return maxNum;
}
}
2、Java AC 方法2,发现这个比方法1快了10ms左右。

/**
* Definition for a point.
* class Point {
* int x;
* int y;
* Point() { x = 0; y = 0; }
* Point(int a, int b) { x = a; y = b; }
* }
*/
public class Solution {
public int maxPoints(Point[] points) {
if(points == null || points.length == 0){
return 0;
}
int n = points.length;
if(n == 1 || n == 2){
return n;
}
Point[] newPoints = new Point[n];
int k = 0;
Map<String, Integer> numMap = new HashMap<String, Integer>();
for(int i = 0; i < n; i++){
int x = points[i].x;
int y = points[i].y;
String xy = x + "_" + y;
int num = 1;
if (numMap.containsKey(xy)) {
num += numMap.get(xy);
}else {
newPoints[k] = new Point(x, y);
k++;
}
numMap.put(xy, num);
}
n = k;
int maxNum = 0;
for(int i = 0; i < n; i++){
for(int j = i+1; j < n; j++){
int tempNum = 0;
tempNum += numMap.get(newPoints[i].x + "_" + newPoints[i].y)
+ numMap.get(newPoints[j].x + "_" + newPoints[j].y);
for (k = j+1; k < n; k++) {
int num1 = (newPoints[k].y - newPoints[i].y)*
(newPoints[j].x - newPoints[i].x);
int num2 = (newPoints[j].y - newPoints[i].y)*
(newPoints[k].x - newPoints[i].x);
if (num1 == num2) {
tempNum += numMap.get
(newPoints[k].x + "_" + newPoints[k].y); ;
}
}
maxNum = Math.max(tempNum, maxNum);
}
}
for ( int value : numMap.values()) {
maxNum = Math.max(value, maxNum);
}
return maxNum;
}
}