inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

2주만에 통과하는 알고리즘 코딩테스트 (2024년)

이모스 관련 질문

해결된 질문

325

kyg8821

작성한 질문수 6

1

안녕하세요. 선생님!

백준 17611번 코드를 아래와 같이 작성했는데, 계속 고쳐봐도 "틀렸습니다"만 돌아와서 질문 남깁니다...
코드가 너무 더러워서 최대한 주석을 달아봤는데.. 이해하시는 데 도움이 됐으면 하는 마음입니다 ㅠㅜ

from collections import defaultdict
import sys
input = sys.stdin.readline

# input
n = int(input())
arr = []
min_x, min_y = sys.maxsize, sys.maxsize
dicH, dicV = defaultdict(list), defaultdict(list)

for _ in range(n):
    x, y = map(int, input().split()) # 꼭지점 입력
    dicH[x].append(y) # 수평으로 선분을 위치한다고 생각하고 그래프를 시계방향으로 90도 돌렸을 때 높이마다 존재하는 선분의 양 꼭지점을 모아둔 리스트
    dicV[y].append(x) # 수직으로 선분을 위치한다고 했을 때, 높이마다 존재하는 선분의 양 꼭지점을 모아둔 리스트
    min_x, min_y = min(min_x, x), min(min_y, y)

# 높이마다 꼭지점을 정렬
for key in dicH:
    dicH[key] = sorted(dicH[key])

for key in dicV:
    dicV[key] = sorted(dicV[key])

# 누적합을 할 리스트 생성
prefixX, prefixY = [0 for _ in range(1_000_001)], [0 for _ in range(1_000_001)]

# 이모스 적용
for key in dicH:
    length = len(dicH[key]) # 각 높이마다 꼭지점의 개수를 구하고
    temp = 0
    while temp < length - 1: # 꼭지점을 두 개씩 짝지어 1과 -1 추가
        prefixY[dicH[key][temp] - min_y] += 1 # 누적합 리스트에 값을 올바른 위치에 추가하기 위해 min_y를 빼 시작점이 0이 되도록 함
        prefixY[dicH[key][temp + 1] - min_y] -= 1
        temp += 2 # 완료하면 두 칸 이동

for i in range(1, 1_000_001):
    prefixY[i] += prefixY[i - 1]

for key in dicV:
    length = len(dicV[key])
    temp = 0
    while temp < length - 1:
        prefixX[dicV[key][temp] - min_x] += 1
        prefixX[dicV[key][temp + 1] - min_x] -= 1
        temp += 2

for i in range(1, 1_000_001):
    prefixX[i] += prefixX[i - 1]

h = max(prefixY)
v = max(prefixX)

print(max(h, v))

 

python 코딩-테스트 알고리즘

답변 2

0

코딩 센세

제 정답 코드입니다!

 

참고 부탁드립니다!

# https://www.acmicpc.net/problem/17611

# 관찰 :
# 수직이동, 수평이동이 반복된다.
# 위로 기둥이 나오면, 이어서 아래로 기둥이 나온다.
# 가장 우측 지점에 도달하면 suffix로 변경된다. ( 하지만 무시해도 계산된다. )
# 개똥벌레 문제랑 동일한 로직이지만, 수직 + 수평 2번 반복된다.

# 아이디어 :
# 먼저 횡이동을 무시하고 모든 기둥을 나열해서 카운팅 해준다.

# -500,000 ~ 500,000
hn = [0]*1001000
wn = [0]*1001000

# 입력을 먼저 받는 방법(o)
# 입력을 받으면서 하는 방법
height = []
width = []
for n in range(int(input())):
    x, y = map(int, input().split())
    y = y + 500000
    x = x + 500000

    width.append(x)
    height.append(y)


maxW = max(width)
minW = min(width)

maxH = max(height)
minH = min(height)


#마지막줄은 계산하지 못하기 때문에 미리 더해주고 빼준다.
a1, b1 = width[0],width[-2]
a2, b2 = height[0],height[-2]

wn[min(a1,b1)] += 1
wn[max(a1,b1)] -= 1

hn[min(a2,b2)] += 1
hn[max(a2,b2)] -= 1

#반복문을 돌려서 프리픽스를 하기 위해 1과 -1을 더해준다
for i in range(n-1):
    # 홀수는 무조건 x값은 동일, y값만 변경된다.
    # if i % 2 == 0:
    a = min(height[i], height[i+1])
    b = max(height[i], height[i+1])
    if a != b:
        hn[a] += 1
        hn[b] -= 1
    # 짝수는 반대다!
    # if i % 2 == 1:
    c = min(width[i], width[i+1])
    d = max(width[i], width[i+1])
    if c != d:
        wn[c] += 1
        wn[d] -= 1
    
#프리픽스 배열을 만든다.
prefix_h = [0]*1001000
prefix_w = [0]*1001000

# 정답을 출력한다.
# answer = 0
for h in range(minH-2, maxH):
    prefix_h[h+1] = prefix_h[h] + hn[h+1]
    # print("h",prefix_h[h+1])
    # answer = max(answer, prefix_h[h+1])

for k in range(minW-2, maxW):
    prefix_w[k+1] = prefix_w[k] + wn[k+1]
    # print("k",prefix_w[k+1])
    # answer = max(answer, prefix_w[k+1])

print(max(max(prefix_h),max(prefix_w)))

0

인프런 AI 인턴

안녕하세요, 인프런 AI 인턴입니다.
kyg8821님, 백준 17611번 문제에서 “틀렸습니다”가 뜨는 원인을 함께 찾아보겠습니다.

주어진 코드를 분석해보면 이모스 알고리즘을 사용하여 문제를 해결하고자 하셨네요. 이모스 알고리즘은 많은 구간에 대한 누적합을 효율적으로 계산할 때 유용한 방법입니다. 이를 통해 구간별로 선분의 개수를 찾아내 최대를 구하는 문제 해결 방식을 채택하셨습니다.

코드 내에서

  1. 각 꼭지점을 수직, 수평 선분 리스트에 추가하고,
  2. 누적합 리스트(prefixX, prefixY)를 생성하여 이모스 알고리즘을 적용하고,
  3. 각각의 누적합 배열에서 최댓값을 구하여 그 중 더 큰 값을 결과로 출력하고 있습니다.

문제의 조건에 따라 이 같은 풀이 방식이 적합할 수 있으나, “틀렸습니다” 결과가 나타나는 것은 코드 내에 논리적 오류가 존재할 가능성이 있습니다.

오류를 찾기 위해 다음 사항들을 확인해볼 수 있습니다.
- 입력받은 선분 정보가 정확하게 처리되고 있는지,
- 선분의 시작과 끝을 표시할 때 짝지어 처리하고 있는 부분이 올바르게 구현되었는지,
- 누적합을 구할 때 모든 필요한 범위를 고려하고 있는지,
- 수평과 수직 선분의 누적합을 구하는 과정에 예외 사항 없이 올바르게 구현되었는지 확인해보시기 바랍니다.

또한, 테스트 케이스를 몇 가지 예외적인 상황으로 추가하여 제대로 동작하는지 살펴보시고, 선분 정보를 입력받을 때 조건에 맞게 처리하는 부분이 있는지도 재검토해볼 필요가 있습니다.

위 사항들을 면밀히 점검하시고, 그래도 문제를 찾지 못할 경우 해당 강의의 커뮤니티 질문&답변 게시판을 통해 질문하신다면 강사님께서 더욱 상세한 답변을 제공해 주실 수 있을 것입니다.

도움이 필요하시면 언제든 문의해주시고, 앞으로도 알고리즘 공부에 많은 성취가 있기를 바랍니다!

dp[x]가 최대값이라고 확신할수 있는 이유

0

44

1

1090번 문제 질문

0

150

1

유니온파인드

0

112

1

투포인터 25:15 질문

1

128

1

#1090번 문제 반례가 궁금합니다.

0

148

1

예제코드 자바입니다

1

186

1

정수론 파트 #2247 문제에 대한 질문입니다!

0

102

0

코드 오류

0

185

1

2강 정수론 문제3 #1407 질문

0

126

0

이차원 배열 (int형)dp로 0 혹은 -1로 체크하는 방법 말고 boolean형 배열로 체크해서 바로 리턴해줄 수 없나요?

0

154

0

1717번 최적화

0

112

0

백준 22988 문제 질문

1

193

2

[Python] 백준 1090번 문제

1

226

3

강의자료에서

1

162

2

2503 문제 제한 조건 질문!

1

249

2

백준 22988 번 문제

1

193

1

추가 강의 순서

1

180

2

(*문제 풀이)1090 테스트케이스 1번 C++

1

221

2

7강 RGB 색칠하기 질문 있습니다.

1

160

2

정수론 약수 빠르게 구하기 질문

1

257

1

1090 문제의 2, 3번째 아이디어는 결국 같은거 아닌가요?

1

373

2

1090 문제 관련하여 맨해튼 거리 최솟값에 대해 질문 있습니다.

1

223

2

누적합 문제 3번 질문

1

216

2

기억 ( 누적합 ) 강의 11660 문제

1

163

2