这周问题求解遇到了一个“莫须有”的编程作业,莫名其妙地做了,就发到这里跟大家交流一下吧。题目是问平面上有一堆点,问这堆点中最多有多少个点能共线。在此用了一种较为直白的解决办法,即找到过每个点的最多共线的线,再对所有的点做一遍找到即可,用时N2log(N)。代码贴到下面,请大家指教。
#ifndef POINT_H
#define POINT_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
class Point
{
public:
double x, y;
Point() { x = y = 0; }
Point(double xx, double yy) { x = xx; y = yy; }
Point operator+(Point a);
Point operator-(Point a);
Point operator*(Point a)const;
Point operator=(Point a) { x = a.x; y = a.y; return *this; }
//bool onLine(Point a,Point b);//for deciding whether the two points lie on the same line
double distance();//return the distance to the original point
void show();
};
class Line
{
public:
Point p, q;
Point vectorPoint;
bool flipped;//for making it easier to calculate
Line() { p = Point(0, 0); q = Point(0, 1); flipped = false; }
Line(double px, double py, double qx, double qy);
Line(Point pp, Point qq) :p(pp), q(qq) { vectorPoint = q - p; flipped = false; }
Line operator=(Line l) { p = l.p; q = l.q; vectorPoint = q - p; return *this; }
void show();
bool operator==(Line &l);//this defination is valid in sense of vector
bool operator<(const Line &l)const ;
bool operator<=(const Line &l)const;
void flip();
};
#endif
#include "point.h"
double Point::distance()
{
return sqrt(x*x + y*y);
}
Point Point::operator+(Point a)
{
return Point(x + a.x, y + a.y);
}
Point Point::operator-(Point a)
{
return Point(x - a.x, y - a.y);
}
Point Point::operator*(Point a)const
{//defined for chacheng
return Point(x*a.y, y*a.x);
}
void Point::show()
{
printf("(%.3lf,%.3lf)\n", x, y);
}
Line::Line(double px, double py, double qx, double qy)
{
p = Point(px, py);
q = Point(qx, qy);
vectorPoint = q - p;
flipped = false;
}
bool Line::operator==(Line &l)
{
Point temp(vectorPoint.x*l.vectorPoint.y, vectorPoint.y*l.vectorPoint.x);
return temp.x == temp.y;
}
bool Line::operator<(const Line &l)const
{
//printf("In comp (%.3lf %.3lf)a'is (%.3lf,%.3lf)\n", vectorPoint.x, vectorPoint.y, l.vectorPoint.x, l.vectorPoint.y);
Point temp(vectorPoint.x*l.vectorPoint.y, vectorPoint.y*l.vectorPoint.x);
return temp.x > temp.y;
}
bool Line::operator<=(const Line &l)const
{
Point temp(vectorPoint.x*l.vectorPoint.y, vectorPoint.y*l.vectorPoint.x);
return temp.x - temp.y >= 0;
}
void Line::show()
{
printf("The points are (%.2lf,%.2lf) (%.2lf,%.2lf)",p.x,p.y,q.x,q.y);
printf("whose ignVector is(%.2lf,%.2lf)", vectorPoint.x, vectorPoint.y);
if (flipped)
printf("And has been flipped.\n");
printf("\n");
}
void Line::flip()
{//for flipping a given line
flipped = !flipped;
q.x = 2 * p.x - q.x;
q.y = 2 * p.y - q.y;
vectorPoint = q - p;
}
if (temp == lines[i])
counter++;
else {
ignCounter[i - 1] = counter;
temp = lines[i];
lastIndex = i;
counter = 0;
i--;
}
}
ignCounter[lines.size() - 1] = counter;
int max = 0;
int maxIndex = 0, maxIndexStart = 0;
for (int i = 0; i < lines.size(); i++) {
if (max <= ignCounter[i]) {
max = ignCounter[i];
maxIndex = i;
}
}
if (ignCounter[maxIndex - 1] > 0)
maxIndexStart = maxIndex;
else {
for (int i = maxIndex - 1; i >= 0; i--) {
if (ignCounter[i] > 0) {
maxIndexStart = i + 1;
break;
}
}
}
sameLineCollections[p] = max+1;
sameLinePoints[p].clear();
for (int i = maxIndexStart; i <= maxIndex; i++) {
if (lines[i].flipped)
lines[i].flip();
sameLinePoints[p].push_back(lines[i].q);
}
sameLinePoints[p].push_back(points[p]);
}
void solve()
{
for (int i = 0; i < n; i++)
cycleForOnePoint(i);
int answer = 0;
int index = 0;
for (int i = 0; i < n; i++) {
if (sameLineCollections[i] > answer) {
answer = sameLineCollections[i];
index = i;
}
}
printf("Max number of points on a line:%d\n", answer);
printf("One such line contains:");
for (int i = 0; i < sameLinePoints[index].size(); i++)
printf("(%.3lf,%.3lf)\t", sameLinePoints[index][i].x, sameLinePoints[index][i].y);
printf("\n");
}
int main()
{
printf("Please input the number of your points:");
while (scanf("%d", &n) != EOF) {
if (n < 2) {
printf("Should be more than two points!\n");
printf("Please input the number of your points:");
continue;
}
double x, y;
for (int i = 0; i < n; i++) {
scanf("%lf %lf", &x, &y);
points[i] = Point(x, y);
}
solve();
printf("Please input the number of your points:");
}
return 0;
}