【编程练习】视力表

题目来源:牛客,阿里巴巴编程题(2星),第10题

题目描述

在这里插入图片描述

题解

这道题的本质就是实现 C n m \text{C}_n^m Cnm,ans = C N 2 a \text{C}_{N^2}^a CN2a+ C N 2 − a b \text{C}_{N^2-a}^b CN2ab+ C N 2 − a − b c \text{C}_{N^2-a-b}^c CN2abc
代码如下:

import math
p = 998244353
def power(x,y):     #求x的y次方
    global p
    res = 1
    while y:
        if y % 2 != 0:
            res *= (x%p)
        y >>= 1
        x *= (x%p)
    return res

def comb(n,m): # Cnm
    global p,power
    a = (math.factorial(n))%p
    b = (power(math.factorial(m),(p-2)))%p
    c = (power(math.factorial(n-m),(p-2)))%p
    return a*b*c%p


def main():
    global comb,p
    N,a,b,c,d = map(int,input().split())
    ans = comb(N*N,a)*comb(N*N-a,b)*comb(N*N-a-b,c)%p
    print(ans)
    return

if __name__ == '__main__':
    main()

知识点:实现组合数 C n m \text{C}_n^m Cnm计算的三种方法

法一:直接计算
C n m \text{C}_n^m Cnm的计算公式为 n ! m ! ∗ ( n − m ) ! \frac{n!}{m!*(n-m)!} m!(nm)!n!。当n和m较小时,可直接利用该公式进行计算:

import math
ans = math.factorial(n)//(math.factorial(m)*math.factorial(n-m))

新姿势:math.factorial(n)返回n的阶乘;

法二:用定义式递归
递推表达式: C n m = C n − 1 m − 1 + C n − 1 m \text{C}_n^m=\text{C}_{n-1}^{m-1}+\text{C}_{n-1}^m Cnm=Cn1m1+Cn1m
所以,代码实现如下:
注意递归出口

def comb(n,m):
	if m==1:
		return n
	elif m==n:
		return 1
	else:
		return comb(n-1,m-1)+comb(n-1,m)

法三:逆元+快速幂
当n和m较大时,题目一般会要求返回对p取模之后的结果,这时问题就转换成求解(a/b)%p的结果,其中,a为n!,b为m!*(n-m)!。

为求解(a/b)%p,首先介绍逆元的概念:
当a和p互素,若b满足(a*b)%p=1,则b为a%p的逆元。

有了这个概念,我们就可以对(a/b)%p做如下转换:
假设c为b%p的逆元,即(c*b)%p=1,则:
(a/b)%p = (a/b*1)%p
= (a/b*(b*c)%p)%p
= a*c%p
= (a%p)*(c%p)%p

这样,(a/b)%p就转换成了乘法问题。

下面,利用费马小定理求解逆元:
费马小定理:当p为质数,且a%p!=0时,则 a p − 1 % p = 1 a^{p-1}\%p=1 ap1%p=1
也就是说, a p − 2 ∗ a % p = 1 a^{p-2}*a\%p=1 ap2a%p=1,即 a p − 2 a^{p-2} ap2是a%p的逆元。

现在,再利用快速幂计算 a p − 2 a^{p-2} ap2,之后就可大功告成。

总结一下,我们要求解的目标是n!/(m!*(n-m)!)%p,
首先,我们需要求解(m!*(n-m)!)%p的逆元,也就是分别求解m!%p和(n-m)!%p的逆元,记作b和c。
接着,当求解完逆元b和c,即可计算n!/(m!*(n-m)!)%p,即n!*b*c%p。

总结起来,利用逆元+快速幂计算 C n m \text{C}_n^m Cnm的代码如下:

import math
p = 998244353
def power(x,y):     #求x的y次方,快速幂
    global p
    res = 1
    while y:
        if y % 2 != 0:
            res *= (x%p)
        y >>= 1
        x *= (x%p)
    return res
def comb(n,m):
	global p,power
	a = (math.factorial(n))%p
	b = (power(math.factorial(m),p-2))%p
	c = (power(math.factorial(n-m),p-2))%p
	return a*b*c%p

ref:https://blog.csdn.net/bianxia123456/article/details/105151104;

猜你喜欢

转载自blog.csdn.net/zyl_wjl_1413/article/details/124116284
今日推荐