문제 정보
https://www.acmicpc.net/problem/2477
문제
시골에 있는 태양이의 삼촌 댁에는 커다란 참외밭이 있다. 문득 태양이는 이 밭에서 자라는 참외가 도대체 몇 개나 되는지 궁금해졌다. 어떻게 알아낼 수 있는지 골똘히 생각하다가 드디어 좋은 아이디어가 떠올랐다. 유레카! 1m2의 넓이에 자라는 참외 개수를 헤아린 다음, 참외밭의 넓이를 구하면 비례식을 이용하여 참외의 총개수를 구할 수 있다.
1m2의 넓이에 자라는 참외의 개수는 헤아렸고, 이제 참외밭의 넓이만 구하면 된다. 참외밭은 ㄱ-자 모양이거나 ㄱ-자를 90도, 180도, 270도 회전한 모양(┏, ┗, ┛ 모양)의 육각형이다. 다행히도 밭의 경계(육각형의 변)는 모두 동서 방향이거나 남북 방향이었다. 밭의 한 모퉁이에서 출발하여 밭의 둘레를 돌면서 밭경계 길이를 모두 측정하였다.
예를 들어 참외밭이 위 그림과 같은 모양이라고 하자. 그림에서 오른쪽은 동쪽, 왼쪽은 서쪽, 아래쪽은 남쪽, 위쪽은 북쪽이다. 이 그림의 왼쪽위 꼭짓점에서 출발하여, 반시계방향으로 남쪽으로 30m, 동쪽으로 60m, 남쪽으로 20m, 동쪽으로 100m, 북쪽으로 50m, 서쪽으로 160m 이동하면 다시 출발점으로 되돌아가게 된다.
위 그림의 참외밭 면적은 6800m2이다. 만약 1m2의 넓이에 자라는 참외의 개수가 7이라면, 이 밭에서 자라는 참외의 개수는 47600으로 계산된다.
1m2의 넓이에 자라는 참외의 개수와, 참외밭을 이루는 육각형의 임의의 한 꼭짓점에서 출발하여 반시계방향으로 둘레를 돌면서 지나는 변의 방향과 길이가 순서대로 주어진다. 이 참외밭에서 자라는 참외의 수를 구하는 프로그램을 작성하시오.
입력
첫 번째 줄에 1m2의 넓이에 자라는 참외의 개수를 나타내는 양의 정수 K (1 ≤ K ≤ 20)가 주어진다. 참외밭을 나타내는 육각형의 임의의 한 꼭짓점에서 출발하여 반시계방향으로 둘레를 돌면서 지나는 변의 방향과 길이 (1 이상 500 이하의 정수) 가 둘째 줄부터 일곱 번째 줄까지 한 줄에 하나씩 순서대로 주어진다. 변의 방향에서 동쪽은 1, 서쪽은 2, 남쪽은 3, 북쪽은 4로 나타낸다.
출력
첫째 줄에 입력으로 주어진 밭에서 자라는 참외의 수를 출력한다.
접근방법
참외밭의 전체 면적을 어떻게 구할 수 있을까? => 전체 사각형에서 작은 사각형을 빼자
전체 사각형의 넓이는 어떻게 구할 수 있을까? => 가로, 세로 길이를 따로 저장하고 최대값을 이용해서 구하자
작은 사각형의 넓이는 어떻게 구할 수 있을까?
=> 최대 가로길이, 세로길이와 바로 인접해 있는 양 변의 길이를 빼면 작은 사각형의 가로 세로를 구할 수 있다!
1차 풀이(오답)
fruit = int(input()) #면적당 참외
cL = [] # 세로 리스트
rL = [] # 가로 리스트
for _ in range(6): # 6각형 이라 6번
d, meter = map(int, input().split())
if d == 1 or d == 2:
cL.append(meter)
else:
rL.append(meter)
# print(cL)
# print(rL)
all = max(cL)*max(rL)
cut = min(cL)*min(rL)
# print(all, cut)
bap = all-cut
# print(bap)
dap = bap * fruit
print(dap)
단순 무식하게 푼 방법
1, 2 번 방향을 가지면 세로 리스트 || 3, 4 번 방향을 가지면 가로 리스트
각각 가로 세로 리스트에 넣어주고 메서드를 통해서 최대값과 최소값을 구했다.
예제만 맞고 나머지는 다 틀리는 문제 4%에서 멈췄다.
2차 풀이(오답)
fruit = int(input()) #면적당 참외
allL = []
cL = [] # 세로 리스트
rL = [] # 가로 리스트
for _ in range(6): # 6각형 이라 6번
d, meter = map(int, input().split())
allL.append(meter)
if d == 1 or d == 2:
cL.append(meter)
else:
rL.append(meter)
# 큰 사각형 넓이
allS = max(cL) * max(rL)
#작은 사각형의 세로
mcIdx = allL.index(max(cL))
nearR1 = (allL[mcIdx-1])
nearR2 = (allL[mcIdx+1])
if nearR1 < nearR2:
cutR = nearR2 - nearR1
else:
cutR = nearR1 - nearR2
# cutR 작은사각형의 세로
#작은 사각형의 가로
mrIdx = allL.index(max(rL))
# print(mrIdx)
nearC1 = (allL[mrIdx-1])
nearC2 = (allL[mrIdx+1])
if nearC1 < nearC2:
cutC = nearC2 - nearC1
else:
cutC = nearC1 - nearC2
cutS = cutR * cutC
bap = allS - cutS
print(bap*fruit)
가장 긴 변의 인접한 양 변을 뺀 값이 작은 사각형의 가로, 세로 값이라는것을 알게 되었다.
인접한 양 변을 구하기 위해서 이전과는 다르게 모든 변의 길이를 리스트에 집어 넣어 주었다.
가장 큰 사각형을 구하기 위한 max 함수는 그대로 사용했다.
index 메서드를 통해서 전체 길이 리스트에서 가장 긴 가로, 세로변의 인덱스 위치를 찾았다.
이를 토대로 +1, -1 을 통해서 인접한 양 변의 길이를 찾을 수 있었다.
하지만 인덱스가 끝에 위치하게 된다면 문제가 생긴다.
-1 은 파이썬의 특징을 통해서 가장 끝 값을 구할 수 있지만
+1 은 인덱스를 벗어나게 돼 버린다.
3차 풀이(통과)
fruit = int(input()) #면적당 참외
allL = []
cL = [] # 세로 리스트
rL = [] # 가로 리스트
for _ in range(6): # 6각형 이라 6번
d, meter = map(int, input().split())
allL.append(meter)
if d == 1 or d == 2:
cL.append(meter)
else:
rL.append(meter)
# 큰 사각형 넓이
allS = max(cL) * max(rL)
#작은 사각형의 세로
mcIdx = allL.index(max(cL))
nearR1 = allL[(mcIdx - 1) % 6]
nearR2 = allL[(mcIdx + 1) % 6]
if nearR1 < nearR2:
cutR = nearR2 - nearR1
else:
cutR = nearR1 - nearR2
# cutR 작은사각형의 세로
#작은 사각형의 가로
mrIdx = allL.index(max(rL))
nearC1 = allL[(mrIdx - 1) % 6]
nearC2 = allL[(mrIdx + 1) % 6]
if nearC1 < nearC2:
cutC = nearC2 - nearC1
else:
cutC = nearC1 - nearC2
# cutC 작은 사각형의 가로
cutS = cutR * cutC
bap = allS - cutS
print(bap*fruit)
인덱스를 벗어나는 문제를 해결하기 위해 % 연산을 이용했다.
6각형 밭이기 때문에 6으로 나눈 나머지는 0~5 까지로
전체 길이 리스트의 인덱스를 벗어나지 않는다.
느낀점
밭 모양이 요상해서 거기에 현혹된 앞으로 주어지는 수준높은 문제들은 사진을 활용하는 경우가 많던데
사진에 현혹당하지 말고 문제를 제대로 읽어서 차근차근 접근하자!
스터디 기간 내에 해결하고 싶었지만 문제 해결 키포인트를 찾는데 어려움을 느꼈다.
스터디원의 접근방식을 듣고 문제를 해결할 수 있었다.
문제를 해결할때 예제만 보고 속단하지 않는 버릇을 들여야겠다.
이번 문제도 예제는 통과하지만 예제의 순서만 바꾸어도 다른 답이 나오는데 이를 알아채지 못한게 아쉽다.
간만에 메서드를 많이 활용했다.
'컴퓨터 > Algorithm' 카테고리의 다른 글
백준 15649 N과 M (1) (파이썬) (0) | 2022.09.05 |
---|---|
백준 2667 단지번호붙이기(파이썬) (0) | 2022.09.04 |
백준 7576 토마토(파이썬) (0) | 2022.09.02 |
SWEA 4875. [파이썬 S/W 문제해결 기본] 5일차 - 미로(파이썬) (0) | 2022.08.24 |
백준 2628 종이자르기(파이썬) (0) | 2022.08.21 |