解方程

复习一下解方程

0X00 解线性方程

用「高斯消元法」解线性方程

面试题 16.03. 交点

883. 高斯消元解线性方程组

过程都写注释里面了,想一次写对真的挺难的

def gauss(n, mat):
    eps, r = 1e-6, 0
    for c in range(n):
        # 找出该列的绝对值最大值
        t = r
        for i in range(r+1, n, 1):
            if abs(mat[i][c]) > abs(mat[t][c]): t = i
        # 把最大列所属的那一行交换到 r 行上,初等行变换
        mat[t], mat[r] = mat[r], mat[t]
        # 如果该列全为 0 则跳过这一列
        if abs(mat[r][c]) < eps: continue

        # 将所有数除以第一个数
        for i in range(n, c-1, -1): mat[r][i] /= mat[r][c]
        # 将下面所有的数字变为 0
        for i in range(r+1, n, 1):
            if abs(mat[i][c]) < eps: continue
            for j in range(n, c-1, -1):
                mat[i][j] -= mat[i][c] * mat[r][j]
        r += 1
    if r < n:
        for i in range(n-1, r-1, -1):
            if abs(mat[i][-1]) > eps: return 2
        return 1
    
    for i in range(n-1, -1, -1):
        for j in range(n-1, i, -1):
            mat[i][-1] -= mat[i][j] * mat[j][-1]
    return 0
t = gauss(n, mat)
if t == 0:
    for i in range(n): print("{:.2f}".format(mat[i][-1]))
elif t == 1:
    print("Infinite group solutions")
else:
    print("No solution")

与此相同的还有解异或线性方程

884. 高斯消元解异或线性方程组 基本一模一样

def gauss():
    r = 0
    for c in range(n):
        # print(a)
        t = -1
        for i in range(r, n):
            if a[i][c] == 1:
                t = i
                break
        # print(r, t, a[t][c])
        if t == -1: continue
        a[t], a[r] = a[r], a[t]
        
        for i in range(r+1, n):
            if not a[i][c]: continue
            for j in range(c, n+1):
                a[i][j] ^= a[r][j]
        r += 1
        
    if r < n:
        for i in range(r, n):
            if a[i][-1]: return 2
        return 1
    
    for i in range(n-1, -1, -1):
        for j in range(i+1, n):
            a[i][n] ^= a[i][j] * a[j][n]
    
    return 0

0X01 解不等式

可以用图论的方法解不等式,假设有 a, b 两个非负整数。无非就是以下五种情况

  • a == b
  • a > b
  • a b
  • a < b
  • a b

放在图论中,我们有节点 a, b 如果有一条从 a 指向 b 的权重为 1 的边。那么就有 dist[b] > dist[a] + 1,如果有一条权重为 0 的边那么就有 dist[b] dist[a]。

因此,我们只需把不等式放在图论中,并建立一个虚拟原点,就能求出所有值的最大或最小值。比如这个题目:

1169. 糖果

求至少,就是求距离最大。举个例子有两个合法的不等式: a > b 和 a b 我们最终取的也是 a > b。所以在计算距离的时候取的是最大值。

利用 spfa 计算所有点距离虚拟原点的距离。

def spfa(start):
    dist = [float("-inf")] * (1+n)
    dist[start] = 0
    st = [False] * (1+n)
    st[start] = True
    q = [start]
    cnt = [0] * (1+n)
    while q:
        v1 = q.pop()
        st[v1] = False
        for v2, w in g[v1]:
            if dist[v2] < dist[v1] + w:
                dist[v2] = dist[v1] + w
                cnt[v2] = cnt[v1] + 1
                if cnt[v2] >= n+1:
                    print(-1)
                    return
                if not st[v2]:
                    q.append(v2)
                    st[v2] = True
    # print(dist)
    print(sum(dist))

你可能感兴趣的:(解方程)