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

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;
    }
}


你可能感兴趣的:(【九度】题目1548:平面上的点 && 【LeetCode】Max Points on a Line)