2020安徽程序设计省赛 I美丽几何
在平面上有n 个点,初始每个点的美丽值都为0,任意选择两个点组成一条直线,对于每一条直线,如果存在一个点,这个点到这条直线的距离小于其他n-3 个点到这条直线的距离,那么我们把这个点的美丽值加1。为了简化输出,我们只需要输出所有点的美丽值的异或值,保证三点不共线。
解题思路
据美丽值的定义:对于每一条直线,如果存在一个点,这个点到这条直线的距离小于其他点到这条直线的距离,那么我们把这个点的美丽值加1。求解所有的点的美丽值,即对于每一条直线,寻找距离其最近的一个点(若有多个点到直线距离相同则全部不计)。 想要完成上述过程,最朴素的思想是,先用O(n^2)的时间复杂度枚举出所有的直线,然后再用O(n)的时间复杂度枚举每个点到直线的距离,最后求出所有点的美丽值并输出异或的结果。这样的算法时间复杂度恒为O ( n 3 ) O(n^3)O(n 3)
代码语言:javascript复制#include <iostream>
#include <ostream>
#include <vector>
#include <cmath>
using namespace std;
class Point {
private:
int x, y, beauty = 0;
public:
Point(int a, int b)
{
x = a;
y = b;
}
int getX() { return x; }
int getY() { return y; }
int getBeauty() { return beauty; }
void addBeauty() { beauty ; }
bool operator==(Point a)
{
if (a.x != this->x)
{
return false;
}
else if(a.y != this->y)
{
return false;
}
return true;
}
};
class Line {
private:
Point p1, p2;
public:
Line(const Point& _p1, const Point& _p2):p1(_p1), p2(_p2)
{
p1 = _p1;
p2 = _p2;
}
friend double distance(Line &p, Point &q)
{
double x1 = p.p1.getX(), y1 = p.p1.getY();
double x2 = p.p2.getX(), y2 = p.p2.getY();
double x = q.getX(), y = q.getY();
double distance = 0.0;
distance = ((x-x1)*(y2-y1)-(x2-x1)*(y-y1))/sqrt((x2-x1)*(x2-x1) (y2-y1)*(y2-y1));
return abs(distance);
}
friend ostream& operator<<(ostream& out, Line& l)
{
out << "A: (" << l.p1.getX() << "," << l.p1.getY() << "), "
<< "B: (" << l.p2.getX() << "," << l.p2.getY() << ")" << endl;
return out;
}
Point getPoint1() { return p1; }
Point getPoint2() { return p2; }
};
vector<Line> getLines(vector<Point>& points)
{
vector<Line> lines;
int size = points.size();
for(size_t i = 0; i < size; i )
{
for(size_t j = i 1; j < size; j )
{
Line line(points[i], points[j]);
lines.push_back(line);
}
}
return lines;
}
void computeBeauty(vector<Line>& lines, vector<Point>& points)
{
for(int i = 0; i < lines.size(); i )
{
bool beauty = true, flag = false;
int minIndex = 0;
double min;
for(int j = 0; j < points.size(); j )
{
if (points[j] == lines[i].getPoint1() || points[j] == lines[i].getPoint2())
{
continue;
}
double dis = distance(lines[i], points[j]);
if(!flag)
{
min = dis;
minIndex = j;
flag = true;
}
else if (dis < min)
{
min = dis;
minIndex = j;
} else if (dis == min)
{
beauty = false;
break;
}
}
if(beauty && flag)
{
points[minIndex].addBeauty();
}
}
}
int main()
{
int n, x, y, result = 0;
vector<Point> points;
cin >> n;
for(int i = 0; i < n; i )
{
cin >> x >> y;
Point p(x, y);
points.push_back(p);
}
vector<Line> lines = getLines(points);
// for(size_t i = 0; i < lines.size(); i )
// {
// cout << "line " << i 1 << ": " << lines[i];
// }
computeBeauty(lines, points);
result = points[0].getBeauty();
//cout << "beauty 0 = " << result << endl;
int i = 1;
for(auto it = points.begin() 1; it != points.end(); it )
{
//cout << "beauty " << i << " = " << it->getBeauty() << endl;
result ^= it->getBeauty();
i ;
}
cout << result << endl;
return 0;
}