作者寄語:學習中總結的一些問題,難免有紕漏,歡迎**!
一.**說明
通常在面試題目在可以看到「
求穿過二維平面上最多點的直線
」,此類問題中,比較重要的是「
特殊問題怎麼轉換為常規問題
」,這正是程式設計思想的核心,下面我將沿著這個思路進行解決上述問題。
二.解決思路
首先我在這裡使用「倒推法」的思路,也就是通常所說的「
由果索因
」法進行分析上述問題,分為下面三個步奏;
第一
:「定位結果」;
依據題目要求,可以得知,本題需要的結果是一條
y=kx+b
的直線,限制條件是「
穿過的點最多
」,這就是需要的結果,轉到第二步;
第二:「常規化轉換」;
有了上述定位的結果,我們可以依據
結果導向
的方法進行問題的常規化轉化 ;
(1)第一步轉化為「
怎麼通過若干個點得到一條直線,並讓這條直線穿過最多的點」,
由數學知識可知:
「兩點確定一條直線。」
穿過最多的點
即兩兩確定的直線在同一條直線上
;那麼,現在的問題就可以轉化為「
得到兩兩確定的直線特徵方程
」並且對直線特徵方程進行統計,重複最多的那條就是穿過點最多的那條直線;
(2)第二步轉化為「
平面上n個點最多能確定幾條直線(考慮重複點),並對確定的直線進行樣本統計,得到重複最多的那條直線
」。類似於
「握手問題」,
可知平面上n個點最多能確定n(n-1)/2條直線(注意剔除重複點),並把這些直線方程做樣本統計得出重複最多的直線方程。這又可以轉換為「求陣列中每個不同元素出現的次數」即元素樣本統計;
(3)陣列中元素樣本統計可以轉化為「陣列排序進行重複元素的統計」或借助「map容器插入進行重複元素的統計」;
通過上述的轉化我們達到了特殊問題常規化的轉換的目的,下面第三個步奏就是進行編碼前的
模組劃分設計
,這個非常重要,直接決定了你的**的可讀性和通用擴充套件性;
第三:「模組設計」
模組劃分設計我遵守的原則就是「
最小顆粒度
」的劃分原則,這種設計的好處就是有利於**的迭代開發,易於擴充套件。自頂向下逐步設計。
(1)第一層「由點確定直線方程的函式」和「統計確定的直線方程出現的次數的函式」;
(2)第二層,設計儲存點和直線方程的資料結構;
經過上面分析設計,我們就可以進行編碼了。
三.**實現
#include#include #include#include #include using namespace std;
struct pt
;struct line
return k < rhs.k;
}return bvertical < rhs.bvertical;
}bool operator == (const line&rhs) const
return k == rhs.k;
}return bvertical == rhs.bvertical;}};
//n個點集合兩兩組合產生直線
void creakline(vector&pointstruct, vector&lineslop);
//兩個點組合產生直線的基本公式
void calslope(pt pt1, pt pt2, line &lineslope);
//利用插入到map統計得出line結構體個數的統計
void inserttomap(vector&lineslop, std::map&outmap);
//得出line結構體重複次數最多的那個結構體
void fineline(std::map&outmap);
//主函式
void main()
;pt pt2;
pt pt3;
pt pt4;
pt pt5;
pt pt6;
pointset.push_back(pt1);
pointset.push_back(pt2);
pointset.push_back(pt3);
pointset.push_back(pt4);
pointset.push_back(pt5);
pointset.push_back(pt6);
vectoralllineslop;
mapoutlineslop;
creakline(pointset, alllineslop);
inserttomap(alllineslop, outlineslop);
fineline(outlineslop);
system("pause");
}void creakline(vector&pointstruct, vector&lineslop)}}
void calslope(pt pt1, pt pt2, line &lineslope)
else
}void inserttomap(vector&lineslop, std::map&outmap)
else
++vbegin;
} outmap = testmap;
}void fineline(std::map&outmap)
}bool bvertical = maxline.bvertical;
float k = maxline.k;
float b = maxline.b;
if (bvertical)
else
}}
四.思想總結
1.程式模組劃分直接決定**處理流程的簡潔度和可讀性可擴充套件性。
2.特殊問題常規化轉化是絕大部分問題的解決方法
穿過點最多的直線
題目描述 在二維平面上,有一些點,請找出經過點數最多的那條線。給定乙個點集vectorp和點集的大小n,沒有兩個點的橫座標相等的情況,請返回乙個vector,代表經過點數最多的那條直線的斜率和截距。struct point point int xx,int yy class denseline ve...
求二維平面上共線最多的點數
思想為 統計每個點的各個斜率的直線上有多少個點 c include include include include include 隨機數通用公式 a rand n 其中的a是起始值,n是整數的範圍 要取得 a,b 的隨機整數,使用 rand b a a 要取得 a,b 的隨機整數,使用 rand ...
平面上N個點,求斜率最大的那條直線通過的兩點
平面上n個點,每兩個點都確定一條直線,求出斜率最大的那條直線所通過的兩個點 斜率不存在的情況不考慮 時間效率越高越好。關於這道題,網上已經給出了解答要點 3個點a,b,c,把它們的按x座標排序。假設排序後的順序是abc,那麼有兩種情況 1.abc共線,則k ab k bc k ac 2.abc不共線...