1 条题解

  • 1
    @ 2026-9-5 19:55:02

    Python

        import sys
        input = sys.stdin.read().split()
        ptr = 0
        N = int(input[ptr]); ptr += 1
        G = int(input[ptr]); ptr += 1
        R = int(input[ptr]); ptr += 1
        RR = R * R
    
        p = []
        for _ in range(N):
            x = int(input[ptr]); ptr += 1
            y = int(input[ptr]); ptr += 1
            p.append((x, y))
    
        g = []
        for _ in range(G):
            x = int(input[ptr]); ptr += 1
            y = int(input[ptr]); ptr += 1
            g.append((x, y))
    
        def dot(a, b):
            return a[0] * b[0] + a[1] * b[1]
    
        def cross(a, b):
            return a[0] * b[1] - a[1] * b[0]
    
        def sub(a, b):
            return (a[0] - b[0], a[1] - b[1])
    
        def sqrlen(a):
            return a[0] * a[0] + a[1] * a[1]
    
        def check_circle(p1, p2, o):
            v = sub(p2, p1)
            w = sub(o, p1)
            d2v = sqrlen(v)
            if d2v == 0:
                return sqrlen(w) > RR
            t = dot(w, v)
            if t <= 0:
                return sqrlen(w) > RR
            if t >= d2v:
                return sqrlen(sub(o, p2)) > RR
            cr = cross(v, w)
            left = cr * cr
            right = RR * d2v
            return left > right
    
        def is_edge(i, j):
            d = abs(i - j)
            if d == 1:
                return True
            if d == N - 1:
                return True
            return False
    
        ok = [[False] * N for _ in range(N)]
        for i in range(N):
            for j in range(i + 1, N):
                if is_edge(i, j):
                    continue
                valid = True
                for o in g:
                    if not check_circle(p[i], p[j], o):
                        valid = False
                        break
                ok[i][j] = valid
                ok[j][i] = valid
    
        dp = [[0] * N for _ in range(N)]
        # length:子多边形顶点数目
        for length in range(4, N + 1):
            for l in range(N):
                r = l + length - 1
                if r >= N:
                    break
                best = 0
                for k in range(l + 1, r):
                    # 方案1:分割对角线 l-k
                    t1 = dp[l][k] + dp[k][r]
                    if ok[l][k]:
                        t1 += 1
                    # 方案2:分割对角线 k‑r
                    t2 = dp[l][k] + dp[k][r]
                    if ok[k][r]:
                        t2 += 1
                    cur = max(t1, t2)
                    if cur > best:
                        best = cur
                dp[l][r] = best
        print(dp[0][N - 1])
    
    if __name__ == "__main__":
        main()
    
    
    
    • 1

    信息

    ID
    2590
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    12
    已通过
    1
    上传者