1. 程式人生 > 實用技巧 >洛谷 P2181 對角線

洛谷 P2181 對角線

P2181 對角線

傳送門

題目描述

對於一個nn個頂點的凸多邊形,它的任何三條對角線都不會交於一點。請求出圖形中對角線交點的個數。

例如,66邊形:

輸入格式

輸入只有一行一個整數nn,代表邊數。

輸出格式

輸出一行一個整數代表答案。

輸入輸出樣例

輸入 #1 3 輸出 #1 0 輸入 #2 6 輸出 #2 15

說明/提示

資料規模與約定

對於 %50% 的資料, 保證 3≤n≤100。
對於 %100% 的資料,保證 3≤n≤105。


解題思路:開始我以為是個純幾何問題,然後,我開始找規律,從3開始然後並沒看出規律(可能是我太菜了),
在思索一番之後我還是看了下大佬的思路,看完後恍然大悟,我們知道交點是由兩根線組成的,也就是說需要四個頂點為這兩根線的組成做貢獻


想通了這個,我們就不難發現,我們求的交點個數相當於是求在這個多邊形的交線中求出兩個不同交線的個數,也就是在多邊形的頂點中選取四個不同頂點的數目(還是很好理解的吧)
到了這裡我們發現這個問題是一個組合數學的問題結果就是Cn4,就是在n個元素中選取四個的情況總數。
然後你以為就完了嘛,看一眼資料,1e5直接爆long long,但是我們不用寫高精度,這裡有個比較巧妙的方法:
n*(n-1)*(n-2)*(n-3)/24==n*(n-1)/2*(n-2)/3*(n-3)/4
先來說說為什麼這麼做能保證結果是整數
n和n-1是兩個相鄰的數,2的倍數一定是個偶數,而n和n-1必定有一個數為偶數(相鄰的兩個數必定有一個為2的倍數)

相鄰的三個數必定有一個為3的倍數,那麼4也就同理(其實這是初中的知識)

那麼可得如下程式碼:

  • #include<bits/stdc++.h>
    using namespace std;
    #define ll unsigned long long
    #pragma-GCC-optimize("-Ofast");
    int main(void)
    {
        ios::sync_with_stdio(false);
        ll n;
        cin>>n;
        cout<<n*(n-1)/2*(n-2)/3*(n-3)/4<<endl;
    }

    附上大佬的題解:

    傳送門