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;1、C++ AC
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
****************************************************************/
#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;2、Java AC 方法1
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 方法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;
}
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;
}
}
/**
* 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;
}
}