三足鼎立
三足鼎立
題目
當三個國家中的任何兩國實力之和都大于第三國的時候,這三個國家互相結盟就呈“三足鼎立”之勢,這種狀態是最穩定的。
現已知本國的實力值,又給出 n 個其他國家的實力值。我們需要從這 n 個國家中找 2 個結盟,以成三足鼎立。有多少種選擇呢?
輸入格式:
輸入首先在第一行給出 2 個正整數 n(2≤n≤1052≤n≤10^52≤n≤105
 ?)和 P(P≤109??P≤10^9??P≤109?? ),分別為其他國家的個數、以及本國的實力值。隨后一行給出 n 個正整數,表示n 個其他國家的實力值。每個數值不超過 109??10^9??109??,數字間以空格分隔。
輸出格式:
在一行中輸出本國結盟選擇的個數。
輸入樣例:
7 30 42 16 2 51 92 27 35輸出樣例:
9樣例解釋:
能聯合的另外 2 個國家的 9 種選擇分別為:
{16, 27}, {16, 35}, {16, 42}, {27, 35}, {27, 42}, {27, 51}, {35, 42}, {35, 51}, {42, 51}。
思路
本題就是求解可以構成三角形的個數。
 已知一條邊,找另外兩條滿足條件的邊。
 對于三條邊可以構成三角形的條件,我們熟知的是:
 任意兩邊之和大于第三邊。
但是現在需要變通一下(以后記住這個就可以了!!!):
兩條短邊大于長邊
所以本題可以分兩種情況討論:
暴力統計明顯會時間超限,正確做法是:先排序,然后根據上述兩種情況結合二分來統計。
tip: 時間+不太方便的原因這里就不貼圖了,可以在草稿紙上畫畫圖,兩種情況的做法也就很明顯了(也許以后會補上吧~)。
需要注意的是,當給的邊 和 已知邊長度相等時 不要重復統計
代碼
#include <iostream> #include <algorithm> using namespace std; const int N = 1e5+5; int a[N]; int main() {int n,p;cin>>n>>p;for(int i = 1; i <= n; ++i){cin>>a[i];}sort(a+1,a+n+1);int last_pos = 0;int l = 1, r = n;//max = p(a[i] maybe equal b),last_pos:last not greater than pwhile(l <= r){int mid = (l + r) >> 1;if(a[mid] <= p){last_pos = mid;l = mid + 1;}else r = mid - 1;}int ans = 0;//double pointersint pl = 1,pr = last_pos;while(pl < pr){while(pl < pr && a[pl]+a[pr]>p){pr--;}ans += last_pos - pr;pl++;}//max = ai,first_pos:first greater than p/*warning: can't repeatly calculate when max = ai and ai = pfor example in following case:6 61 2 3 4 5 6*/int first_pos = 0;l = 1,r = n;while(l<=r){int mid = (l + r) >> 1;if(a[mid] > p){first_pos = mid;r = mid - 1;}else l = mid + 1;}for(int i = n; a[i]>p&&i>=first_pos; --i){l = 1,r = i;int pos = 0;//first greater than a[i]-pwhile(l <= r){int mid = (l + r) >> 1;if(a[mid] > a[i]-p){pos = mid;r = mid - 1;}else l = mid + 1;}if(pos) ans += i - pos;}cout<<ans<<endl;return 0; }$Daily English
Down to Gehenna or up to the Throne,He travels the fastest who travel alone.
 無論時下到煉獄還是登上王位,獨行的人走得最快。
總結
 
                            
                        - 上一篇: 阶乘的非零尾数
- 下一篇: Android SDK Manager
