백준 문제풀이

백준 10227 - 삶의 질 [Python]

Vermeil 2022. 4. 29. 02:46

https://www.acmicpc.net/problem/10227

 

10227번: 삶의 질

첫째 줄에 4개의 정수 R, C, H, W 가 주어진다. R과 C는 각각 도시의 행과 열의 크기를 나타내고, H와 W는 각각 홍준이가 정한 영역에서의 행과 열의 크기이다. 그 다음 R개의 줄에 각각 C개의 quality ran

www.acmicpc.net

[알고리즘 분류]

이분 탐색, 누적 합

 

 

정답을 \(x\)라고 가정하자.

주어진 배열에서 \(x\)보다 큰 수는 1, 작은 수는 -1로 바꾼다면, 합이 0인 \(H\) x \(W\) 직사각형이 배열 내에 존재할 것이다.

 

이 아이디어를 이용하여 이분 탐색으로 적절한 \(x\)를 찾을 수 있고, 시간복잡도 \(O(RC(lg(RC)))\)에 문제를 풀 수 있다.

 

75줄부터 보면 된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
import sys, math
import heapq
 
from dataclasses import dataclass
from collections import deque
from bisect import bisect_left, bisect_right
 
input = sys.stdin.readline
 
hqp = heapq.heappop
hqs = heapq.heappush
 
 
# input
def ip(): return int(input())
def sp(): return str(input().rstrip())
 
 
def mip(): return map(int, input().split())
def msp(): return map(str, input().split().rstrip())
 
 
def lmip(): return list(map(int, input().split()))
def lmsp(): return list(map(str, input().split()))
 
 
# gcd, lcm
def gcd(x, y):
    while y:
        x, y = y, x % y
    return x
 
 
def lcm(x, y):
    return x * y // gcd(x, y)
 
 
# prime
def isPrime(x):
    if x <= 1return False
    for i in range(2int(x ** 0.5+ 1):
        if x % i == 0:
            return False
    return True
 
 
# Union Find
# p = [i for i in range(272727)]
 
def find(x):
    if x == p[x]:
        return x
    p[x] = find(p[x])
    return p[x]
 
 
def union(x, y, s):
    x = find(x)
    y = find(y)
 
    if x != y:
        p[y] = x
 
 
def getPow(a, x):
    ret = 1
    while x:
        if x & 1:
            ret = (ret * a) % MOD
        a = (a * a) % MOD
        x >>= 1
    return ret
 
 
############ Main! #############
 
n, M, h, w = mip()
= []
= [[0 for _ in range(3003)] for _ in range(3003)]
pf = [[0 for _ in range(3003)] for _ in range(3003)]
 
ans = 10**9
for i in range(n):
    a.append(lmip())
 
lo = 0
hi = 10000000
while lo <= hi:
    m = (lo + hi) // 2
    for i in range(n):
        for j in range(M):
            if a[i][j] <= m:
                p[i][j] = -1
            else:
                p[i][j] = 1
    for i in range(n):
        for j in range(M):
            pf[i][j] = pf[i-1][j] + pf[i][j-1- pf[i-1][j-1+ p[i][j]
    fl = False
    g = False
    for i in range(h - 1, n):
        if fl: break
        for j in range(w - 1, M):
            if pf[i][j] - pf[i-h][j] - pf[i][j-w] + pf[i-h][j-w] <= 0:
                fl = True
                break
    if fl:
        hi = m - 1
    else:
        lo = m + 1
 
print(lo)
 
######## Praise greedev ########
cs

시간이 어마어마하다..!

'백준 문제풀이' 카테고리의 다른 글

5/16~5/22 PS  (0) 2022.05.22
백준 13159 - 배열 [Python]  (0) 2022.05.02
백준 20669 - Close to You [Python]  (0) 2022.04.24
백준 17634 - 이상한 기계 [Python]  (0) 2022.04.19
백준 16993 - 연속합과 쿼리 [Python]  (0) 2022.04.15