1. 程式人生 > >(第八場)G Counting regions 【歐拉公式】

(第八場)G Counting regions 【歐拉公式】

quic complete 滿足 stream was namespace eve reg efi

題目鏈接:https://www.nowcoder.com/acm/contest/146/G

G、Counting regions

| 時間限制:1 秒 | 內存限制:128M
Niuniu likes mathematics. He also likes drawing pictures. One day, he was trying to draw a regular polygon with n vertices. He connected every pair of the vertices by a straight line as well. He counted the number of regions inside the polygon after he completed his picture. He was wondering how to calculate the number of regions without the picture. Can you calculate the number of regions modulo 1000000007? It is guaranteed that n is odd.

輸入描述:

The only line contains one odd number n(3 ≤ n ≤ 1000000000), which is the number of vertices.

輸出描述:

Print a single line with one number, which is the answer modulo 1000000007.
技術分享圖片
備註: The following picture shows the picture which is drawn by Niuniu when n=5. Note that no more than three diagonals share a point when n is odd.

示例 1

輸入

3

輸出

1

示例2

輸入

5

輸出

11

題意概括:

給你一個正n邊形,將n個頂點兩兩連邊,問內部有多少個區域。n是奇數。

官方題解:

歐拉公式:F=E-V+2
內部交點個數:C(n,4)
一條線段會被一個交點分成兩段,所以x條直線的交點會多分出來x條線段,利用V 可以算出E。

解題思路:

根據歐拉公式:F:面數;E:邊數;V:頂點數

當V >= 4時,多邊形滿足 V-E+F = 2;

因為N是奇數,所以任意選取四個頂點連接,兩條對角線相交於一點,交點兩兩不重合,所以內部交點個數為 C(n, 4);

而內部邊數 = 對角線數 + 內部交點數*2 (即 C(n, 2) + C(n, 4)*2);

最後邊數,結點數已知,可求面數。

註意細節:

求組合時數據偏大有取模操作,除法運算要通過逆元轉換為乘法,這裏求逆元的方法是用費馬小定理。

AC code:

技術分享圖片
 1 ///歐拉公式+費馬小定理求逆元
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <iostream>
 5 #include <cmath>
 6 #include <cstring>
 7 #define INF 0x3f3f3f3f
 8 #define ll long long int
 9 #define mod 1000000007
10 using namespace std;
11 
12 ll N, V, E;
13 ll quick_pow(ll a, ll b)
14 {
15     ll ans = 1;
16     while(b)
17     {
18         if(b&1) ans = ans*a%mod;
19         a = a*a%mod;
20         b>>=1;
21     }
22     return ans;
23 }
24 int main()
25 {
26     scanf("%lld", &N);
27     V = N*(N-1)%mod*(N-2)%mod*(N-3)%mod*quick_pow(24,mod-2)%mod;  ///內部交點
28     E = (V*2 + (N*(N-1)/2)%mod)%mod;    ///邊數
29     V = (V + N)%mod;  ///頂點數
30     ll F = ((E-V+1)%mod+mod)%mod;  ///面數
31     printf("%lld\n", F);
32     return 0;
33 }
View Code

(第八場)G Counting regions 【歐拉公式】