zoukankan      html  css  js  c++  java
  • P3799 妖梦拼木棒 (组合数学)

    题目背景

    上道题中,妖梦斩了一地的木棒,现在她想要将木棒拼起来。

    题目描述

    有n根木棒,现在从中选4根,想要组成一个正三角形,问有几种选法?

    输入输出格式

    输入格式:

    第一行一个整数n

    第二行n个整数,a1,a2,……an(0<ai<=5000),代表每根木棒的长度。

    输出格式:

    一行一个整数,对1e9+7取模

    输入输出样例

    输入样例#1: 
    4 1 1 2 2
    输出样例#1: 
    1

    说明

    对于30%的数据 N<=5000

    对于100%的数据 N<=100000

    Solution

    很显然这是个数学水题,我都会做...

    因为是要找 4 根小木棍.

    所以很显然这个正三角形的组成是:

    n1 , n2 , n1+n2 , n1+n2;

    所以公式就是 :

     Ansn = C1num [ j ]*C1num [ n - j ]*C2num [ n ]

    其中,num数组代表当这种长度的木板所有的数量.然后 j 为 从 1 枚举到 n/2 .

    然后求解即可.

    代码

     
    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=100008;
    #define ll long long 
    #define mo 1000000007 
    #define C1(x) (x) 
    #define C2(x) ((x)*((x)-1)/2)
    ll n,maxl,ans;
    ll num[maxn],a[maxn];
    int main()
    {
        scanf("%lld",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%lld",&a[i]);
            num[a[i]]++;
            maxl=max(a[i],maxl);
        }
        for(int i=2;i<=maxl;i++)
        {
            if(num[i]>=2)
            {
                for(int j=1;j<=(i/2);j++)
                {
                    ll k=i-j;
                    if(k!=j)
                    ans+=(C1(num[j])%mo)*(C1(num[k])%mo)*C2(num[i])%mo;
                    else
                    ans+=(C2(num[j])%mo)*(C2(num[i])%mo)%mo;
                    ans%=mo;
                }
            }
        }
        cout<<ans<<endl;
    }
  • 相关阅读:
    服务器安装软件
    SQL server
    改变下blog思维
    react 父子组件互相通信
    linux下,文件的权限和数字对应关系详解
    Linux 下非root用户使用docker
    Two 观察者 observer pattern
    one 策略模式 strategy
    ssm maven spring AOP读写分离
    Unknown column in 'where clause'
  • 原文地址:https://www.cnblogs.com/Kv-Stalin/p/9085556.html
Copyright © 2011-2022 走看看