首先發出題目鏈接:
鏈接:https://ac.nowcoder.com/acm/contest/883/H
來源:牛客網
涉及:思維,簡單平面幾何
點擊這裏回到2019牛客暑期多校訓練營解題—目錄貼
題目如下:
此題的方法有好多種,我就講講我的方法
首先對所有點按照先將 從小到大,後將 從小到大排序。
那麼這條直線可以經過第 和第 個點的中間。假設第 個點的座標爲 ,第 個點的座標爲
那麼這兩個點可能滿足下面的位置關係:
1.兩個點不在同一垂線上,即 。
由於排序之後,一半的點的 值肯定比點 的 值要小,另一半的點的 值肯定比 的 值要大,所以完全可以按照上圖一樣,在這兩個點的中點處畫一條垂直線。
但是這條直線可能不經過任何整數座標點,所以需要將這條直線稍微傾斜,如下圖
由於所有點的 值 值都小於1000,而上面直線的經過的兩個整點在 的區域外面,且在區域內不經過任何整點,直線也剛好經過 和 的中點,把平面內的點分成了等量的兩部分。
if(a.x!=b.x) printf("%d 999000000 %d %d\n",a.x,b.x,(a.y+b.y)-999000000);//a,b分別指Point[n/2]與Point[n/2+1]
當然把垂直線向左傾斜和向右傾斜都是同樣的效果。上圖是把垂直線向左傾斜的結果。
2.兩個點恰好在同一垂線上,即
不妨令
對於這種情況,可以做一條直線,如下圖
但是注意,這條直線只能向左傾斜,不能向右傾斜。因爲在排序的時候是按照當 相同時, 從小到大排序的,所以可能存在某些點的 值與這兩個點的 值相同,但是高於點 ,這些點要被歸納於直線右邊的點,才能使得直線左右兩半部分的點數量相同。
printf("%d 999000000 %d %d\n",a.x-1,b.x+1,(a.y+b.y)-999000000);
代碼如下:
#include <iostream>
#include <algorithm>
#define x first
#define y second
using namespace std;
typedef long long ll;
typedef pair<int,int> P;//P的平面上的點類型
int t,n;//題目所給變量
bool comp(P a,P b){
if(a.x!=b.x) return a.x<b.x;
else return a.y<b.y;
}
int main(){
cin>>t;
while(t--){
scanf("%d",&n);
P point[1005];
int i;
for(i=1;i<=n;i++){
scanf("%d%d",&point[i].x,&point[i].y);
}
sort(point+1,point+n+1,comp);//對所有點按x從小到大,y從小到大排序
P a=point[n/2],b=point[n/2+1];
if(a.x!=b.x) printf("%d 999000000 %d %d\n",a.x,b.x,(a.y+b.y)-999000000);//點在同一垂線上
else printf("%d 999000000 %d %d\n",a.x-1,b.x+1,(a.y+b.y)-999000000); //點不在同一垂線上
}
return 0;
}