知乎上的题目,号称难题,其实数学方法并不难。不过要枚举列出所有方案,还是需要找个合适的算法。
凑个热闹,写了一段 fortran ,并改写成 Python。核心算法是以三进制数来模拟(枚举)分组方案,检验合法的,计数、输出。
fortran 代码
! fortran
! 2024-07-01
! szw_sh@163.com
integer :: a(6),b(3)
character(2) :: s(6)=(/'a1','a2','a3','a4','b1','b2'/)
aa: do i=0,3**6-1 ! 用三进制数模拟分组
ii=i
b=0
do j=6,1,-1
k=mod(ii,3)+1
a(j)=k
b(k)=b(k)+1
ii=ii/3
if(j.lt.5.and.(k.eq.a(5).or.k.eq.a(6))) cycle aa
end do
if(minval(b).eq.0) cycle
m=m+1 ! 计数
write(*,'(a$)') '(' ! 输出具体分组的情况
do j=1,3
n=0
do k=1,6
if(a(k).ne.j) cycle
if(n.eq.1) write(*,'(a$)') '+'
write(*,'(a$)') s(k)
n=1
end do
if(j.lt.3) write(*,'(a$)') ','
end do
write(*,'(a$)') '), '
if(mod(m,3).eq.0) write(*,*)
end do aa
write(*,'(a,g0)') 'total = ',m ! 输出总数
end
Python 代码
# Python
# 2024-07-02
# szw_sh@163.com
a = [0] * 6 # 初始化数组
b = [0] * 3
s = ['a1', 'a2', 'a3', 'a4', 'b1', 'b2']
m = 0 # 计数器
for i in range(3**6): # 使用三进制数模拟分组
ii = i
b = [0] * 3
for j in range(5, -1, -1):
k = (ii % 3)
a[j] = k
b[k] += 1
ii //= 3
if j<4 and (k==a[4] or k==a[5]):
b = [0]
break
if min(b) == 0:
continue
m += 1
print('(', end='') # 输出具体分组
for j in range(3):
n = 0
for k in range(6):
if a[k] != j:
continue
if n == 1:
print('+', end='')
print(s[k], end='')
n = 1
if j < 2:
print(',', end='')
print('), ', end='')
if m % 3 == 0:
print() # 换行
print(f'total = {m}') # 输出总数
计算结果
(a1+a2+a3+a4,b1,b2), (a1+a2+a3+a4,b2,b1), (a1+a2+a3,a4,b1+b2),
(a1+a2+a3,b1+b2,a4), (a1+a2+a4,a3,b1+b2), (a1+a2,a3+a4,b1+b2),
(a1+a2+a4,b1+b2,a3), (a1+a2,b1+b2,a3+a4), (a1+a3+a4,a2,b1+b2),
(a1+a3,a2+a4,b1+b2), (a1+a4,a2+a3,b1+b2), (a1,a2+a3+a4,b1+b2),
(a1+a3+a4,b1+b2,a2), (a1+a3,b1+b2,a2+a4), (a1+a4,b1+b2,a2+a3),
(a1,b1+b2,a2+a3+a4), (a2+a3+a4,a1,b1+b2), (a2+a3,a1+a4,b1+b2),
(a2+a4,a1+a3,b1+b2), (a2,a1+a3+a4,b1+b2), (a3+a4,a1+a2,b1+b2),
(a3,a1+a2+a4,b1+b2), (a4,a1+a2+a3,b1+b2), (b1,a1+a2+a3+a4,b2),
(b2,a1+a2+a3+a4,b1), (b1+b2,a1+a2+a3,a4), (b1+b2,a1+a2+a4,a3),
(b1+b2,a1+a2,a3+a4), (b1+b2,a1+a3+a4,a2), (b1+b2,a1+a3,a2+a4),
(b1+b2,a1+a4,a2+a3), (b1+b2,a1,a2+a3+a4), (a2+a3+a4,b1+b2,a1),
(a2+a3,b1+b2,a1+a4), (a2+a4,b1+b2,a1+a3), (a2,b1+b2,a1+a3+a4),
(b1+b2,a2+a3+a4,a1), (b1+b2,a2+a3,a1+a4), (b1+b2,a2+a4,a1+a3),
(b1+b2,a2,a1+a3+a4), (a3+a4,b1+b2,a1+a2), (a3,b1+b2,a1+a2+a4),
(b1+b2,a3+a4,a1+a2), (b1+b2,a3,a1+a2+a4), (a4,b1+b2,a1+a2+a3),
(b1+b2,a4,a1+a2+a3), (b1,b2,a1+a2+a3+a4), (b2,b1,a1+a2+a3+a4),
total = 48