python 牛客真题 分田地

二分贪心查找

nm=list(input().split())
n=int(nm[0])
m=int(nm[1])
board=[[0]*m for _ in range(n)]
count=0
while count<n:
    num=input()
    for j in range(m):
        board[count][j]=int(num[j])
    count+=1
sums=[[0]*(m+1) for _ in range(n+1)]
left=min([min(_) for _ in board])
right=sum([sum(_) for _ in board])//16 +1
for i in range(1,n+1):
    for j in range(1,m+1):
        sums[i][j]=sums[i-1][j]+sums[i][j-1]-sums[i-1][j-1]+board[i-1][j-1]
def get_sum(x1,y1,x2,y2):
    return sums[x2][y2]+sums[x1][y1]-sums[x1][y2]-sums[x2][y1]
def cansplit(val):#是否还能切的更大
    for r1 in range(1,n-2):
        if get_sum(0,0,r1,m)<4*val: continue
        for r2 in range(r1+1,n-1):
            if get_sum(r1,0,r2,m)<4*val: continue
            for r3 in range(r2+1,n):
                if get_sum(r2,0,r3,m)<4*val: continue
                if get_sum(r3,0,n,m)<4*val: continue
                start,count=0,0
                for i in range(1,m+1):
                    if get_sum(0,start,r1,i)>=val and get_sum(r1,start,r2,i)>=val and get_sum(r2,start,r3,i)>=val and get_sum(r3,start,n,i)>=val:
                        start,count=i,count+1
                        if count==4:
                            return True
    return False

while left<right:
    mid=left+(right-left)//2
    if cansplit(mid):
        left=mid+1
    else:
        right=mid
print(left-1)

猜你喜欢

转载自blog.csdn.net/Neekity/article/details/85391802