合理抽象灵活运用排列组合(洛谷P2181题题解,Java语言描述)
題目要求
P2181題目鏈接
分析
其實,本題是一個數(shù)學(xué)題。。。
首先由題意得,不會有三條對角線交于一點,所以過某一個交點有且只能有2條對角線。
而這兩條對角線實質(zhì)上是確定了4個頂點(也可以看做是一個四邊形的兩條對角線交于一點,求四邊形的數(shù)量),因此我們只需要確定4個頂點就得到了這個唯一確定的交點。
因此我們只需要求這樣4個頂點的組合有多少個,即從n個頂點中取4個出來的組合數(shù)。
此時,這個問題變成了排列組合問題。。。
根據(jù)組合數(shù)的公式,得:
于是我們就得到了我們解題的核心算法(公式咯): n * (n-1) * (n-2) * (n-3) / 24
但我們這么處理,由于連乘再除,要考慮溢出和精度,所以我們可以化簡。
原式可以化為:
n * (n-1) / 2 * (n-2) / 3 * (n-3) / 4
那為什么這樣一定是對的呢?難道不會因為除不盡卻向下取整而導(dǎo)致錯誤嗎?
事實上是一定除得盡的:
首先n和n-1一定有一個是2的倍數(shù),因此2可以除盡。
同理n,n-1,n-2中一定有一個是3的倍數(shù),因此3可以除盡(除掉2只會消除因數(shù)2而對3沒有影響)
再同理,4也可以除盡。
坑點
還是這個數(shù)值類型的選擇問題。。
你選int還覺得沒問題,一看很和諧,一跑就WA。。。
但換成long才能看出問題:
顯然只能用BigInteger。。。
為啥懶得用BigIntegeer呢,看我AC代碼就知道了,何等的麻煩以及慢…………能不用就別用,但是連乘可以用這個東西保命一下。。
AC代碼(Java語言描述)
import java.math.BigInteger; import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);BigInteger number = scanner.nextBigInteger();scanner.close();BigInteger num1 = new BigInteger("1");BigInteger num2 = new BigInteger("2");BigInteger num3 = new BigInteger("3");BigInteger num4 = new BigInteger("4");number = number.multiply(number.subtract(num1)).divide(num2).multiply(number.subtract(num2)).divide(num3).multiply(number.subtract(num3)).divide(num4);System.out.println(number);} }看看,這個公式,每一次都有“.”,麻煩得很。。。
總結(jié)
以上是生活随笔為你收集整理的合理抽象灵活运用排列组合(洛谷P2181题题解,Java语言描述)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【CSS3】将截断的文字可选的显示出来
- 下一篇: 质因数分解(洛谷P1075题题解,Jav