其他分享
首页 > 其他分享> > 【Kickstart】2019 Round C - Circuit Board

【Kickstart】2019 Round C - Circuit Board

作者:互联网

解法

算出每列往左的长度,然后就能转化成求直方图最大矩形的问题

至于如何求第i行第j列往左有多长,需要每行维护两个双向队列minStackmaxStack和一个左边界l,对于范围(l,j]minStack队头是这个范围内最小值(以及它在的位置),从队头到队尾,值和索引都是递增的
类似地,maxStack队头是这个范围内最大值(以及它在的位置),从队头到队尾,值递减,索引都是递增的

现在如果maxStack[0]-minStack[0]>K,说明极差过大,这时候可以:

# -*- coding:utf-8 -*-

def solve(r,c,k,V):
    from collections import deque
    minStack = [deque() for _ in range(r)]
    maxStack = [deque() for _ in range(r)]
    l = [-1]*r
    ans = 0
    for j in range(c):
        stack = deque([(-1, -1)])
        for i in range(r):
            while minStack[i] and V[i][minStack[i][-1]]>=V[i][j]:
                minStack[i].pop()
            minStack[i].append(j)
            while maxStack[i] and V[i][maxStack[i][-1]]<=V[i][j]:
                maxStack[i].pop()
            maxStack[i].append(j)
            while V[i][maxStack[i][0]]-V[i][minStack[i][0]]>k:
                if maxStack[i][0]<minStack[i][0]:
                    l[i] = maxStack[i].popleft()
                else:
                    l[i] = minStack[i].popleft()
            h = j - l[i]
            while stack and stack[-1][0]>=h:
                hh = stack.pop()[0]
                ans = max(ans, hh * (i-stack[-1][1]-1))
            stack.append((h, i))
        while len(stack)>1:
            h = stack.pop()[0]
            ans = max(ans, h * (r-stack[-1][1]-1))
    return ans


if __name__ == "__main__" :
    t = int(input())
    for round in range(1,t+1):
        r,c,k = map(int,input().split())
        V = [list(map(int,input().split())) for _ in range(r)]
        print("Case #%d: %d"%(round,solve(r,c,k,V)))

标签:maxStack,Kickstart,minStack,pop,stack,range,2019,ans,Round
来源: https://blog.csdn.net/lemonmillie/article/details/100066856