덱으로 이차원 리스트를 만들 수 있다는 것을 처음 알았다..!!
아직도 배울 것이 많다ㅎㅎ
이 문제를 푸는 방법은 그저-!
빡구현!!
할수있다!! 화이팅🔥🔥
1. 숫자들을 리스트 -> 덱으로 만들어 저장한다.
2. 덱으로 저장되어있으므로 rotate를 이용할 수 있다.
3-1. 양옆을 확인하여 동일한 값이 있는지 체크한다.
3-2. 위, 아래를 확인하여 동일한 값이 있는지 체크한다.
4-1. 동일한 값이 있으면 0을 넣는다.
4-2. 없다면 원판을 돌면서 평균을 구하고 원판을 돌면서 원판위 값을 조정한다.
코드 :
from collections import deque
if __name__=="__main__" :
n,m,t = map(int,input().split())
mp = [deque(list(map(int,input().split()))) for _ in range(n)]
for _ in range(t) :
x,d,k = map(int,input().split())
# 0이 아닌 수들의 합
result = 0
# 회전
for i in range(n) :
result += sum(mp[i])
if (i+1)%x == 0:
if d == 0 :
mp[i].rotate(k)
elif d== 1 :
mp[i].rotate(-k)
if result != 0 :
have_to_remove = []
# 같은 반지름의 원반 끼리 비교
for i in range(n) :
for j in range(m-1) :
if mp[i][j] != 0 and mp[i][j] == mp[i][j+1]:
have_to_remove.append((i,j))
have_to_remove.append((i,j+1))
# 맨 처음과 끝 비교
if mp[i][0] != 0 and mp[i][0] == mp[i][-1] :
have_to_remove.append((i,0))
have_to_remove.append((i,m-1))
# 반지름이 다른 원끼리 비교
for j in range(m) :
for i in range(n-1) :
if mp[i][j] != 0 and mp[i][j] == mp[i+1][j]:
have_to_remove.append((i,j))
have_to_remove.append((i+1,j))
# 중복 제거
have_to_remove = list(set(have_to_remove))
for i in range(len(have_to_remove)) :
x,y = have_to_remove[i]
mp[x][y] = 0
# 제거할 숫자가 없다면
if len(have_to_remove) == 0 :
avg_sum = 0
zero_cnt = 0
for i in range(n) :
avg_sum += sum(mp[i])
zero_cnt += mp[i].count(0)
avg = avg_sum / (n*m-zero_cnt)
for i in range(n) :
for j in range(m) :
if mp[i][j] != 0 :
if mp[i][j] > avg :
mp[i][j]-=1
elif mp[i][j] < avg :
mp[i][j] +=1
# 전부 다 0 일때
else :
print(0)
exit(0)
ans = 0
for i in range(n) :
ans += sum(mp[i])
print(ans)
고려해야 할 점들
1.
풀이에서 같은 것들이 발견될 때 바로 0을 바꾸는 것이아니라 리스트에 저장해놓았다가
추후에 set으로 중복을 처리한 후 0으로 만든다.
처음에는 이게 의미가 없다고 생각하여 바로 바로 0으로 만들도록 코드를 만들었었는데 틀렸다.
2개씩만 짝을 짓는 것이 아니라 3개 그리고 그 이상도 동일할 때 함께 0이 될 수 있기 때문이다.
그래서 같은 것들이 발견되면 함께 have_to_remove라는 리스트에 넣는다.
그리고 set()을 통해 중복을 제거할 때는[]안에 []가 있으면 에러가 발생한다.
튜플형태만 set을 통과시켜 중복을 제거할 수 있다.
# 맨 처음과 끝 비교
if mp[i][0] != 0 and mp[i][0] == mp[i][-1] :
have_to_remove.append((i,0))
have_to_remove.append((i,m-1))
have_to_remove.append([i,0]) 이렇게 하면 set를 적용시키지 못한다.
2.
그리고 반지름이 다른 원끼리 인접한 사이에 값이 같은 지 비교할 때
for j in range(m) :
for i in range(n-1) :
으로 문제를 해결한 점이 감명깊었다.
3.
result를 구하지 않아도 문제가 풀릴것같아서 안구하고 풀어봤는데 아니다.
result가 없으면 틀린다.
이유는 (m*n)-zero_cnt로 나누기 때문이다.
result가 0일 때는 zero_cnt가 m*n이 되기때문에 나누는 분모가 0이 되므로 zerodivision 오류가 발생한다.
4.
그리고 mp[i][j]!=0 and 를 조건에 넣는거 기억하자 !
0이되어 사라진 값은 신경쓰지 않기 때문이다.
복습하면서 만든 약간 더 비효율적인(?) 코드 : < delete 값을 처음부터 set으로 만들었다.>
from collections import deque
if __name__=="__main__" :
n,m,t = map(int,input().split())
mp = []
for i in range(n) :
mp.append(deque(list(map(int,input().split()))))
for _ in range(t) :
result = 0
x,d,k = map(int,input().split())
for i in range(n) :
result += sum(mp[i])
if (i+1) % x == 0:
if d == 0 :
mp[i].rotate(k)
else :
mp[i].rotate(-k)
if result > 0 :
delete = set()
for i in range(n) :
for j in range(m-1) :
if mp[i][j]!=0 and mp[i][j] == mp[i][j+1] :
delete.add((i,j))
delete.add((i,j+1))
if mp[i][0]!=0 and mp[i][0] == mp[i][m-1] :
delete.add((i,0))
delete.add((i,m-1))
for j in range(m) :
for i in range(n-1) :
if mp[i][j]!=0 and mp[i][j] == mp[i+1][j] :
delete.add((i,j))
delete.add((i+1,j))
if len(delete) > 0 :
for x,y in delete :
mp[x][y] = 0
else :
zero_cnt = 0
max_v = 0
for i in range(n) :
for j in range(m) :
if mp[i][j] == 0 :
zero_cnt +=1
else :
max_v += mp[i][j]
avg_v = max_v / ((m*n)-zero_cnt)
for i in range(n) :
for j in range(m) :
if mp[i][j]!=0 and mp[i][j]> avg_v : mp[i][j] -=1
elif mp[i][j]!=0 and mp[i][j] < avg_v : mp[i][j] +=1
else :
print(0)
exit(0)
ans = 0
for i in range(n) :
ans += sum(mp[i])
print(ans)
참고 블로그 :
https://hoyeonkim795.github.io/posts/17822/
복습 :
✔ 20220911
'알고리즘 > 백준 문제풀이' 카테고리의 다른 글
[삼성SW역량][Python/BOJ] 백준 21609 상어 중학교(구현) (0) | 2022.08.03 |
---|---|
[삼성SW역량][Python/BOJ] 백준 20058 마법사 상어와 파이어스톰(구현+BFS) (0) | 2022.08.03 |
[삼성SW역량][Python/BOJ] 백준 19238 스타트택시(BFS+구현) (0) | 2022.07.28 |
[삼성SW역량][Python/BOJ] 백준 21610 마법사 상어와 비바라기(구현) (0) | 2022.07.28 |
[삼성SW역량][Python/BOJ] 백준 21608 상어초등학교(구현) (0) | 2022.07.22 |