多个点共线个数问题

这周问题求解遇到了一个“莫须有”的编程作业,莫名其妙地做了,就发到这里跟大家交流一下吧。题目是问平面上有一堆点,问这堆点中最多有多少个点能共线。在此用了一种较为直白的解决办法,即找到过每个点的最多共线的线,再对所有的点做一遍找到即可,用时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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值