第33次CSP认证模拟的教训

在写第三题化学方程式配平的时候,我用的是Python,决定写两个类来更好的实现逻辑。

主要就是Array类,能像numpy那样对整个数组的元素进行操作。

但是写完之后运行总报错有None参与运算或者Array不支持除法等(我寻思着有实现__div__啊)

以下是我收获的教训:

1.魔法方法的增量赋值运算符如__iadd__等实现+=效果的,要返回self,不能没有返回值

我一开始就是没有返回值,导致运算中出现了None

2.除法是truediv而不是div,得和整除floordiv区分

我以为除法就是div,加上pycharm没有提示,就自以为是的用div,导致一直报错
附随便找的一个魔术方法大全

下面贴一下最后通过的代码

class Array:
    def __init__(self, array: list[int]):
        self.array = array

    def __mul__(self, other: int|float):
        return Array([i*other for i in self.array])

    def __rmul__(self, other):
        return self.__mul__(other)

    def __imul__(self, other):
        for i, val in enumerate(self.array):
            self.array[i] = val * other
        return self

    def __truediv__(self, other):
        return Array([i/other for i in self.array])

    def __itruediv__(self, other):
        for i, val in enumerate(self.array):
            self.array[i] = val / other
        return self

    def __sub__(self, other):
        # array - array
        return [self.array[i]-other.array[i] for i in range(len(self.array))]

    def __isub__(self, other):
        for i, val in enumerate(self.array):
            self.array[i] = val - other.array[i]
        return self

    def __add__(self, other):
        # array - array
        return [self.array[i] + other.array[i] for i in range(len(self.array))]

    def __iadd__(self, other):
        for i, val in enumerate(self.array):
            self.array[i] = val + other.array[i]
        return self

    def is_zero(self):
        return all(i==0 for i in self.array)

    def __len__(self):
        return len(self.array)

    def __getitem__(self, item):
        return self.array[item]

    def __repr__(self):
        return str(self.array)


class Matrix:
    def __init__(self, matrix=None):
        if matrix is None:
            self.matrix = [[]]
            self.m = 0
            self.n = 0
        else:
            self.matrix = matrix
            self.m = len(matrix)
            self.n = len(matrix[0])

    def exchange(self, i, j):
        self.matrix[i], self.matrix[j] = self.matrix[j], self.matrix[i]

    def normalize(self, i, j):
        self.matrix[i] /= self.matrix[i][j]

    def eliminate(self, i, j, col):
        if self.matrix[j][col] == 0:
            return
        k = self.matrix[j][col] / self.matrix[i][col]
        self.matrix[j] -= self.matrix[i] * k

    def nonzero_col(self, r, j):
        for i in range(r, self.m):
            if self.matrix[i][j]:
                return i
        return -1

    def __getitem__(self, item):
        return self.matrix[item]

    def __str__(self):
        return str(self.matrix)


def str_process(s: str) -> dict[str, int]:
    dic = {}

    li = []
    start = 0
    for i in range(1, len(s)):
        if s[i].isalpha() and s[i-1].isdigit() or s[i].isdigit() and s[i-1].isalpha():
            li.append(s[start:i])
            start = i
    li.append(s[start:])
    for i in range(0, len(li), 2):
        dic[li[i]] = int(li[i+1])
    return dic

def check(material: list[str]):
    li = [str_process(s) for s in material]
    dic = {}
    for d in li:
        for key in d.keys():
            dic[key] = []
    for d in li:
        for key in dic.keys():
            dic[key].append(d.get(key, 0))
    matrix = Matrix([Array(i) for i in dic.values()])

    if matrix.m < matrix.n:
        return True

    r = 0
    for j in range(matrix.n):
        row = matrix.nonzero_col(r, j)
        if row == -1:
            continue
        if row != r:
            matrix.exchange(r, row)
        matrix.normalize(r, j)
        for i in range(r+1, matrix.m):
            matrix.eliminate(r, i, j)
        r += 1
    if r < matrix.n:
        return True
    else:
        return False


n = int(input())

for _ in range(n):
    m, *mat = input().split()
    print("Y" if check(mat) else "N")

'''
1
4 al2s3o12 n1h5o1 al1o3h3 n2h8s1o4

'''
posted @ 2024-09-12 19:14  faf4r  阅读(4)  评论(0编辑  收藏  举报