2013
11-12

Incidental Points

Unlike a straight line, a straight segment between two points P1, P2 (normally written as P1P2) is a line that links the two points but doesn’t extend beyond them. A third point P3 is said to be incident to P1P2 iff P3 lies on the straight line and between the points P1 and P2. P1P2 is said to include P3. By definition, P1 and P2 are included in P1P2. Write a program to find the segment that includes the most number of given points.

Your program will be tested on one or more test cases. Each test case includes a set of two or more unique points, where the Cartesian coordinates of each point is specified on a separate line using two integers X and Y where 0 ≤ |X|, |Y| < 1,000,000. No test case has more than 1000 points. An input line made of two or more '-' (minus signs) signals the end of a test case. An extra input line of two or more '-' (minus signs) follow the last test case.

For each test case, output the result on a single line using the following format:

k. n

Where k is the test case number (starting at 1), and n is the number of points on the segment.

1 1
1 5
5 9
9 5
5 5
3 2
5 3
----
1 5
5 1
1 1
5 5
--
--------

1. 4
2. 2

//* @author: 82638882@163.com
import java.io.*;
import java.util.*;
public class Main
{
public static void main(String[] args) throws IOException
{
InputStreamReader is=new InputStreamReader(System.in);
BufferedReader in=new BufferedReader(is);
String[] ss;
String s;
int count=0;
while(true)
{
count++;
node[] arr=new node[1001];
node[] pp=new node[1001];
int i=0,j,zNum,maxNum,x,y,p,max=-1, a=0;
while(true)
{
s=in.readLine();
if(s.charAt(0)=='-'&&s.charAt(1)=='-') break;
ss=s.split(" ");
x=Integer.parseInt(ss[0]);
y=Integer.parseInt(ss[1]);
arr[a]=new node(x,y);
pp[a]=new node();
a++;
}
if(a==0) break;
for(i=0;i< a-1;i++)
{
int k=0;
zNum=maxNum=-1;
for(j=i+1;j< a;j++)
{
x=arr[i].x-arr[j].x;
y=arr[i].y-arr[j].y;
if(y==0) zNum++;
else if(x==0) maxNum++;
else
{
p=gcd(Math.abs(x),Math.abs(y));
pp[k].x=x/p;
pp[k].y=y/p;
if(pp[k].x< 0)
{
pp[k].x*=-1;
pp[k].y*=-1;
}
k++;
}
}
max=Math.max(max,Math.max(zNum, maxNum));
int cnt=0;
Arrays.sort(pp, 0, k);
for(j=0;j< k-1;j++)
{
if(pp[j].x==pp[j+1].x&&pp[j].y==pp[j+1].y) cnt++;
else{
if(cnt>max) max=cnt;
cnt=0;
}
}
max=Math.max(max, cnt);
}
System.out.println(count+". "+(max+2));
}
}

static int gcd(int a,int b)
{
if(b==0) return a;
else return gcd(b,a%b);
}
}

class node implements Comparable< node>{
public int x,y;
public node(){}
public node(int a,int b)
{
x=a;
y=b;
}
public int compareTo(node o) {
if(x==o.x) return y-o.y;
return x-o.x;
}
}

1. 代码是给出了，但是解析的也太不清晰了吧！如 13 abejkcfghid jkebfghicda
第一步拆分为 三部分 (bejk, cfghi, d) * C(13,3)，为什么要这样拆分，原则是什么？

2. 问题3是不是应该为1/4 .因为截取的三段，无论是否能组成三角形， x， y-x ，1-y,都应大于0，所以 x<y,基础应该是一个大三角形。小三角是大三角的 1/4.