牛客多校第八场 G-Counting regions(组合数学+几何欧拉公式)

127 篇文章 0 订阅
85 篇文章 2 订阅

Counting regions

这道题呢,其实是一道组合数学的题,再加上欧拉公式。

题意:问边数为奇数的正多边形所有的顶点两两相连,直线所分割的区域数量为多少,答案对 1e9+7 1 e 9 + 7 取模。

我们会发现题目中的图形,除了顶点是不会有三线交于一点的。所以分割区域的区域数量就只取决于点的数量。

现在我们未知:
1. 1. 一共有多少条直线?
2. 2. 这些直线在正多边形内的交点有多少个?

答案 1 1 :我们都知道两点构成一线,所以我们可以构成的直线就是在n个顶点中选两个顶点(顶点两两相连嘛,这样保证了不会有三线交于一点),一共有 C(n,2) C ( n , 2 ) 条。

答案 2 2 :观察题目中的图就会发现,正多边形上的任意四个顶点所连成的两条直线交于唯一的一点。所以我们又可以从组合数学的角度来求交点数量,即C(n,4)个交点。

接下来引入欧拉公式 VE+F=2 V − E + F = 2 ,意思就是只要满足不会有三线交于一点的任意多边形都满足这个公式。( V V 代表点的数量,E代表边的数量, F F 代表所分割的区域数量)

但是我们这里的边数还没有求,通过小数据我们可以找出规律:=+2×,即 E=C(n,2)+2×C(n,4) E = C ( n , 2 ) + 2 × C ( n , 4 )

所以最后 F=EV+1=C(n,2)+2×C(n,4)(C(n,4)+n)+1 F = E − V + 1 = C ( n , 2 ) + 2 × C ( n , 4 ) − ( C ( n , 4 ) + n ) + 1 ,这里为什么只加一呢?因为我们去除了正多边形外面的区域。

先来一份暴力

import java.util.Scanner;
import java.math.BigInteger;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        BigInteger n = in.nextBigInteger();
        BigInteger C_n_2 = n.multiply(n.subtract(BigInteger.ONE)).divide(BigInteger.ONE.add(BigInteger.ONE));
        BigInteger C_n_4 = n.multiply(n.subtract(BigInteger.ONE)).multiply(n.subtract(new BigInteger("2"))).multiply(n.subtract((new BigInteger("3")))).divide(new BigInteger("24"));
        BigInteger ans = C_n_2.add(C_n_4).subtract(n.subtract(BigInteger.ONE)).mod(new BigInteger(""+(int)(1E9+7)));
        System.out.println(ans);
        in.close();
    }
}

再来一份优雅


/*
 * V - E + F = 2
 * F = E - V + 2
 * */
#include<bits/stdc++.h>
typedef long long LL;
const LL mod = 1e9+7;
LL Pow(LL a,LL n)
{
    LL ans = 1, res = a;
    while(n)
    {
        if(n&1) ans = ans * res % mod;
        res = res * res % mod;
        n >>= 1;
    }
    return ans;
}

LL Inv(LL n)
{
    return Pow(n,mod-2);
}

int main()
{
    LL n;
    std::cin>>n;
    // C(n,2)%mod - C(n,4)%mod + 2%mod
    LL E = n*(n-1)%mod*Inv(2);
    LL V = n*(n-1)%mod*(n-2)%mod*(n-3)%mod*Inv(24)%mod;
    LL ans = E+V-n+1;
    std::cout<<ans%mod<<std::endl;
    return 0;
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值