Topcoder SRM 727 TwoDiagonals
题目原文
Bearland can be represented as a horizontal plane with N distinct points, denoting positions of N cities.The i-th city has coordinates (x[i], y[i]).
Limak is planning to build two infinitely long roads in Bearland.One should go northwest, and the other should go northeast (both these directions are tilted exactly 45 degrees from the vertical direction).It implies that the two roads are perpendicular to each other, and that they have an intersection point (this point can be a city but not necessarily).
Roads increase the trade significantly.A city will be happy if it lies on at least one of the two roads.Help Limak and find the maximum possible number of happy cities.
-
- x { 1, 4, 4, 5 }
- y { 3, 0, 2, 3 }
Returns 4There are four cities: (1,3), (4,0), (4,2), (5,3).It's possible to draw two lines in such a way that all cities will be happy: -
- x { 0, 1, 2, 3, 4, 5 }
- y { 2, 2, 2, 2, 2, 2 }
Returns 2The new roads can go through at most two cities in this case.One of many optimal placements is:
题意分析
给定坐标中一些点,在坐标系中画两条相互垂直的先,斜率为正负一,试问如何画这两条线,使得最终在线上的点的个数最多,求出最大点数。
解法分析
因为线的斜率是定的,不同的就是y=x+b中的b了,最开始我想遍历所有b可能的值,存储在其上的点数,后来发现这样的遍历次数无限,因此只需要对每个点计算穿过它的两条线,对于点(x,y),b1=x+y,b2=y-x,建立一个两个map,分别存储斜率不同的两条线,first为不同的b,second为点数,由于交点可能会算重复,因此需要计算两条线的交点是否在所给点集合中,注意这里计算的交点可能是浮点数,而点集中的点都是整点。C++代码如下:
int maxPoints(vector<int> x, vector<int> y) {
map<double,double> neg;
map<double,double> pos;
set<pair<double,double>> point;
int mymax=0;
int temp;
for(int i=0;i<x.size();i++){
neg[x[i]+y[i]]++;
pos[y[i]-x[i]]++;
point.insert(make_pair((double)x[i],(double)y[i]));
}
for(auto n=neg.begin();n!=neg.end();n++){
for(auto p=pos.begin();p!=pos.end();p++){
temp=(int)((*n).second+(*p).second);
if(point.count(make_pair(((*n).first/2-(*p).first/2),((*p).first/2+(*n).first/2))))
temp=temp-1;
mymax=max(mymax,temp);
}
}
return mymax;
}