题目链接
There are always some problems that seem simple but is difficult to solve.
Z Y B ZYB ZYB got N N N distinct points on a two-dimensional plane. He wants to draw a magic line so that the points will be divided into two parts, and the number of points in each part is the same. There is also a restriction: this line can not pass through any of the points.
Help him draw this magic line.
There are multiple cases. The first line of the input contains a single integer T T T ( 1 ≤ T ≤ 10000 1\leq T \leq 10000 1≤T≤10000) indicating the number of cases.
For each case, the first line of the input contains a single even integer N N N ( 2 ≤ N ≤ 1000 2\leq N\leq 1000 2≤N≤1000), the number of points. The following N N N lines each contains two integers x i , y i x_i,y_i xi,yi ( ∣ x i , y i ∣ ≤ 1000 \mid x_i,y_i\mid \leq 1000 ∣xi,yi∣≤1000), denoting the x x x-coordinate and the y y y-coordinate of the i i i-th point.
It is guaranteed that the sum of N N N over all cases does not exceed 2 × 1 0 5 2 \times 10^5 2×105.
在笛卡尔坐标系中有 N N N个点,去找到某一条直线将这 N N N个点划分为两个部分,每个部分点的个数相同,同时该直线不能经过坐标系中任意一个点,找到该直线中的两个整数点。
坐标系中的每个点按照 x x x从小到大排序,若 x x x相同则按照 y y y从小到大进行排序,找到中间点 ( x , y ) (x,y) (x,y),过中间点垂直于 x x x轴的直线 l l l能够将坐标系中的点划分为近似相等的两个部分,由中间点坐标可以得到两个点, a ( x − 1 , y + 1 0 8 ) a(x-1,y+10^8) a(x−1,y+108), b ( x + 1 , y − 1 0 8 ) b(x+1,y-10^8) b(x+1,y−108),(至于为什么加 1 0 8 10^8 108,因为必须要加一个特别大的数才能让垂直的直线变化尽可能的小,而题目中告诉 m a x ( x i ) , m a x ( y i ) max(x_i),max(y_i) max(xi),max(yi)为 1000 1000 1000,而最后答案不能超过 1 0 9 10^9 109,能加的最大数即为 1 0 8 1 0^8 108)过这两点的直线得到过中点 ( x , y ) (x,y) (x,y)且近似为 l l l的一条直线,然后 a a a点的 y y y坐标+1,将直线稍微向上倾斜,点E划分到左边部分,由此得到的直线可以将坐标系中的点划分为两个部分。
#include
const int Max_N=1e3+100;
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
struct Num
{
int x,y;
};
bool cmp(Num a,Num b)
{
if(a.x!=b.x)
return a.x<b.x;
return a.y<b.y;
}
Num num[Max_N];
int main()
{
int t;
cin>>t;
while(t--)
{
int n;
cin>>n;
for(int i=0;i<n;i++)
{
cin>>num[i].x>>num[i].y;
}
sort(num,num+n,cmp);
ll x1=num[n/2-1].x;
ll y1=num[n/2-1].y;
cout<<x1-1<<" "<<(ll)(y1+100000000+1)<<" "<<x1+1<<" "<<(ll)(y1-100000000)<<endl;
}
return 0;
}
在最开始的时候把这道题想的太复杂了,由此陷入了思维泥潭。该题虽然是在二维坐标中,但在划分为两个部分的时候思路只需考虑一维的情况,然后稍微扩展一点便可。