今天在面經中看到的一道手寫**題,題意是在一個二維平面內,有n個點(n < 700),讓你在平面內找到一條直線,使得最多的點落在這條直線上,問最多能落在你找的這條直線上的點數是多少,原題是poj 1118
先不去考慮細節,只從大方向上考慮,這個題的思路是:
我們先選取一個點作為基準點,然後計算其餘點和這個基準點構成的直線的斜率(如果有兩個點和這個基準點構成的直線的斜率是相同的,那麼這三個點是共線的)
這n-1個斜率都計算完成後,將他們排序,然後從左到右掃一遍,看每種斜率有多少個,數量最多的那種斜率的數量+1就是以這個點為基準點的時候最多能夠共線的點的數目
再依次把剩下的點作為基準點,重複上述操作,所有基準點對應的最多能夠共線的點的數目的最大值就是答案
接下來我們來考慮一下實現細節:
1. 這個題涉及到斜率計算,必須要注意有的情況斜率是不存在的,所以當兩個點的橫座標相等時,我們需要特殊處理,而不能去計算斜率
2. 斜率是一個double型別的資料,統計數目時不能用木桶,只能排序之後從左到右掃一遍去數每種斜率的數目(在數的時候記得要把當前斜率是否和上一個斜率相等的條件改成兩者的差的絕對值<1e-6,而不是寫個==)
3. 在具體實現過程中,我用一個pair來記錄斜率,pair中的bool變數用來記錄這個斜率是否存在,如果存在斜率(pair中的bool變數取值為true),pair中的double變數記錄斜率;如果斜率不存在(pair中的bool變數取值為false),pair中的double變數記錄基準點的橫座標(既然斜率不存在,那麼這個點必定是橫座標和基準點的橫座標是相同的)
4. 由於使用了一個pair來記錄斜率,因此需要重新定義一下比較函式:
①我們規定不存在斜率的pair比所有存在斜率的pair都小,即當我們比較一個有斜率的pair和一個沒有斜率的pair的時候,沒有斜率的pair《有斜率的pair
②兩個有斜率的pair,比較他們的斜率大小
③兩個沒有斜率的pair,比較他們的x座標的大小
**如下:
#include #include#include
#include
#include
using
namespace
std;
typedef pair
pdd;
const
int n = 800
;int arrx[n]; //
存放所有點的橫座標
int arry[n]; //
存放所有點的縱座標
int cmp(const pdd& a, const pdd&b)
intmain()
int result = -1
;
for(int i = 0; i < n; i++) else
}sort(arr, arr+cnt, cmp); //
排序
//從左到右掃一遍,找出數量最多的斜率的數量
pdd now = make_pair(false, 1000000000000000
);
int nowcount = 0, maxcount = -1
;
for(int j = 0; j < cnt; j++)
else
}maxcount = max(maxcount, nowcount); //
最後一個斜率的數量沒有被結算,需要手動結算一下
result =max(result, maxcount);
}cout
<< result+1
<< endl; //
結果需要+1
cin >>n ;
}return0;
}
poj 1118 Lining Up 解題報告
題意 給出n個點的整數座標 n 700 ,求一條直線,使得在這條直線上的點數最多,輸出點數。 思路 簡單幾何題。採用幾何中三個點是否在一條直...
POJ3087 Shuffle m Up
本題傳送門 本題知識點 寬度優先搜尋 模擬 map 本題題意有點懵。就是單純的把s1像例子那樣插到s2裡,根本不是什麼寬搜題,因為只是一個方向就可以了。說是搜尋題倒是有點意思,因為要查重。 不過cin還是慢啊,一個cin就把我卡tle了。 所以最後這就是簡單的模擬題,加上一個map 竟然不超時! 。...
poj2653 Pick up sticks
題目大意 給定一系列線段,以及放在平面上的順序,給出沒有被其他覆蓋的線段。 解題關鍵 線段相交的判斷。 滿足兩個條件即可 快速排斥實驗 跨立實驗。 include include include include include include using namespace std typedef ...