PS/풀이 기록장

220829 문제 풀이 기록

2022. 8. 29. 23:38

P3 | 6132 - 전화선

풀이 시간: 1시간

시도 횟수: 2회

체감 난이도: P3

풀이 쓸 의향: 上

풀이

더보기

동일한 수의 연속하는 원소는 반드시 동시에 올리거나 내려야 한다는 점을 잘 파악하여 증명한 뒤, 각 값과 연속되는 구간을 저장한 뒤 그리디하게 가장 작은 값들의 구간부터 1씩 올리면서 최적값 찾기

여담: 다른 사람들은 죄다 DP로 푼 것 같은데 나 혼자만 그리디로 푼 것 같다. 문제 관찰 과정과 그 관찰을 토대로 그리디 알고리즘을 구현하는 과정이 즐거웠다.

 

 

 

 

P5 | 1131 - 숫자

풀이 시간: 1시간 10분

시도 횟수: 2회

체감 난이도: P5

풀이 쓸 의향: 下

풀이

더보기

반드시 겹치는 사이클이 존재하는데, 해당 사이클을 잘 찾아서 연산하기

여담: 문제 보자마자 아이디어 거의 10분만에 떠올려놓고 구현에서 죽쑨거 못찾고 1시간 삽질함; 죽고싶다...

'PS > 풀이 기록장' 카테고리의 다른 글

220831 문제 풀이 기록  (0) 2022.08.31
220830 문제 풀이 기록  (0) 2022.08.30
220828 문제 풀이 기록  (0) 2022.08.28
220827 문제 풀이 기록  (0) 2022.08.27
220826 문제 풀이 기록  (0) 2022.08.27

220828 문제 풀이 기록

2022. 8. 28. 23:11

P3 | 12016 - 라운드 로빈 스케줄러

풀이 시간: 약 50분

시도 횟수: 2회

체감 난이도: P3 하위권

풀이 쓸 의향: 下

풀이

더보기

없어지는 원소들을 잘 관리하면서 세그먼트 트리 활용하기. 크기가 x인 값을 처리할 때 현재 시간이 몇인지 잘 기록하고, 이미 실행이 끝난 프로세스 값을 1로 바꾸면 구간합 세그트리로 해결 가능하다.

여담: 4년 전에는 뭣도 모르고 시간 초과를 냈던 문제인데, 이제야 스스로 해결할 수 있게 되었다. 만세!

딱히 재미있는 관찰이 필요한 게 아니라 세그트리를 잘 활용하기만 하면 풀리는 문제여서 딱히 재미는 없었다.

'PS > 풀이 기록장' 카테고리의 다른 글

220830 문제 풀이 기록  (0) 2022.08.30
220829 문제 풀이 기록  (0) 2022.08.29
220827 문제 풀이 기록  (0) 2022.08.27
220826 문제 풀이 기록  (0) 2022.08.27
220825 문제 풀이 기록  (0) 2022.08.25

220827 문제 풀이 기록

2022. 8. 27. 23:47

P5 | 15808 - 주말 여행

풀이 시간: 30분

시도 횟수: 무려 7회

체감 난이도: P5 하위권

풀이 쓸 의향: 下

풀이

더보기

각 여행지들을 각각 시작점으로 잡고 최대 힙으로 최대 기대치가 되는 다익스트라 돌리기

여담: 정답이 0보다 작을 수 있음을 고려하지 않고 풀다가 혼쭐났음. 아니 영선아 여행 기대치가 음수면 대체 왜 여행을 가는거니??

 

 

P4 | 14927 - 전구 끄기

풀이 시간: X

시도 횟수: 1회

체감 난이도: X

풀이 쓸 의향: 下

풀이

더보기

각 칸은 두번 이상 누를 일 없음 + 맨 윗줄을 어떻게 누르느냐에 따라서 아래쪽을 어떻게 눌러야 하는지 확정적으로 알 수 있음을 이용하여 브루트 포싱

여담: https://www.acmicpc.net/problem/14939 이전에 풀었던 문제와 너무 동일해서 그냥 풀이 박아버렸음... 솔직히 골드 난이도는 진짜 말도 안된다고 생각하고, 사람마다 개인차가 있겠지만 P5 ~ P4 사이인듯.

 

'PS > 풀이 기록장' 카테고리의 다른 글

220829 문제 풀이 기록  (0) 2022.08.29
220828 문제 풀이 기록  (0) 2022.08.28
220826 문제 풀이 기록  (0) 2022.08.27
220825 문제 풀이 기록  (0) 2022.08.25
220824 문제 풀이 기록  (0) 2022.08.24

220826 문제 풀이 기록

2022. 8. 27. 01:59

P5 | 9463 - 순열 그래프

걸린 시간: 20분

체감 난이도: 어쩔수 없이 P5 주는 정도

시도 횟수: 1회

풀이 쓸 의향: 下

풀이:

더보기

장황한 순열 그래프 뭐시기는 낚시용이고 그냥 교차하는 선분의 개수 구하면 됨. 위쪽 노드를  왼쪽부터 순서대로 고르면 (b[a[i]], n) 구간의 합을 구하는 세그트리로 구하면 됨.

여담: 그냥 세그트리 쓰면 풀리는 세그트리용 날먹 문제. seg 구현할때 등호 넣으면 안되는 식에 등호넣어서 5분 날림.

 

 

 

P4 | 1124 - 바닥 장식

걸린 시간: 1시간 30분

체감 난이도: P4 상위권

시도 횟수: 6회

풀이 쓸 의향: 下

풀이:

더보기

(x1, y1)에서 (x2, y2)까지 개수를 어떻게든 열심히 예외처리하면서 크기가 1, 2, 3, 4, 5인 개수 각각 다 구하고 그리디하게 큰것부터 넣어주면서 개수 세기

여담: 내가이겼어내가이겼어내가이겼어내가이겼어내가이겼어내가이겼어내가이겼어내가이겼어내가이겼어내가이겼어내가이겼어내가이겼어내가이겼어내가이겼어내가이겼어내가이겼어내가이겼어내가이겼어내가이겼어내가이겼어내가이겼어내가이겼어내가이겼어내가이겼어내가이겼어내가이겼어내가이겼어내가이겼어내가이겼어내가이겼어내가이겼어

문제 보자마자 풀기싫어서 몸비틀다가 풀이 시작하자마자 문제 잘못읽고 풀다가 때려치려고 하다가 다시 풀다가 틀려서 예외처리하다가 정신이 나가버릴뻔함

저번에 풀었던 리그 (https://www.acmicpc.net/problem/3031)보다 예외 처리랑 구현 더 빡센 문제는 이게 처음인듯

 

풀이 메모

더보기

으악
으악 이게 뭐야
아니 이걸 풀라고? 아니 으악 살려줘 으악

ㅡ ㅣ ㅡ ㅣ ㅡ ㅣ
ㅣ ㅡ ㅣ ㅡ ㅣ ㅡ
ㅡ ㅣ ㅡ ㅣ ㅡ ㅣ
ㅣ ㅡ ㅣ ㅡ ㅣ ㅡ

높이가 5면 당연히 위아래 5인거 넣는게 최적임. 그니까 틀에 딱 맞춰서 넣는게 최적이다.
높이가 6이면? ㅡ 로 돼있는거는 그냥 하나 추가지만, ㅣ로 돼있는거는 5개나 추가되니까, 그리고 어차피 나열되니까
사실 높이가 뭐든지간에 위쪽을 틀에 딱 맞추는게 그냥 최적임
뭐 높이를 맞추든 너비를 맞추든 그게 그거같지만 아무튼 가장 윗변을 맞춰서 가자.
그럼 이제 좌우로 움직이면서 .. 어라 ㅅㅂ 잠깐만?
아냐 이게 맞아

이제 좌우만 따지면 되는데
근데 똑같은 논리로 그럼 좌우도 면에 딱 붙이는게 최적이어야 되는거 아님??
그냥 왼쪽 위에 맞춰서 계산하면 되는거 아님???

아니 문제 잘못읽었네 ㅅㅂㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ
어쩐지 쉬워보이더라
그래도 접근은 비슷하게 하면 될것 같은데...
아니네


일단 문제 파트가 두갠데
1. (x1, y1), (x2, y2)에 있을 때 크기 1인거부터 5인거까지의 개수 구하기
2. 크기 1인거부터 5인거까지 개수가 있을 때, 크기 5 최소 개수만 써서 그거 만들기


근데 2.는 쉬운게
4를 만드려면 어차피 1이 나오게 되어 있음 --> 4 최대한 만들자
3 만들면 1 1 이나 2로 사용 가능한데, 1 만드는게 더 쉬우니까 3 개수에서는 2 최대한 넣고 넣은 후에는 다 1 넣으면 됨
그냥 그리디로 짜면 된다

1번이 문제야 1번이 ㅅㅂ 개귀찮아
이게 가운데 있는 꽉 찬 애들은 그냥 하면 되는데
끝부분 잘라먹기를 해야되는게 참...
개하기싫다
푼사람도 얼마 없겠지
22명이면 생각보다 많네
플4는 풀이를 도전하는 용기에서 나오는 난이도인건가
ㅅㅂ...

2 2 8 8
(2, 2) ~ (5, 2)
(5, 2) ~ (8, 2)


아 괜찮은 방법 없나?

어차피 뭐 좌표 크더라도 왼쪽 위를 왼쪽 위쪽으로 옮기면 무조건 왼쪽 위 좌표는 (10, 10)보다 왼쪽 위로 압축이 가능한데
전체에서 (0, 0) ~ (10, 10)는 그냥 다 저장 해 둔 상태에서, 범위 따라 구현하자

아익

상하좌우 그냥 다 해버리자
안해시발

후.... 그래 그래도 해야지 ㅅㅂ
왼쪽에 겹친 ㅡ 부분의 개수, 오른쪽에 겹친 ㅡ 부분의 개수, 위쪽에 

(8, 5) ~ (20, 16)에서,
(8, 5) ~ (10, 16)에 있는 ㅡ의 개수 : 6, 크기 : 2
(8, 16) ~ (20, 16)에 있는 ㅣ의 개수 : 5, 크기 : 1
나머진 모두 안에 있으니 그냥 하면 됨

ㅇ?ㅇ?ㅁㄴㅇ?ㅁ?ㅃ?!@?# ㅃ!?ㅇㄹㄴ ?ㅁㄴㅇ?ㄹ ㄴㅁㅇ? #? ?

4 0 10 2

 

 

 

 

P3 | 21725 - 더치페이

걸린 시간: 1시간 15분

체감 난이도: P3 중/하위권

시도 횟수: 9회

풀이 쓸 의향: 中

풀이:

더보기

disjoint set으로 합쳐 가되, 작은 집합과 큰 집합을 합칠 때는 작은 집합 값을 정리해주며 진행. 한 그래프 안에서의 총 지출 금액과 각 사람이 지출한 금액을 저장하고, 마지막에 쭉 돌려주면 각 사람이 내야 하는 / 받아야 하는 금액이 전부 나오고, 한명 총무로 삼아서 돈 송금하면 된다.

여담: 돈 0원 송금하면 안된다는 조건 때문에 한번 틀렸고, 다른 별 이상한 실수해서 틀렸던건데 풀이 증명 다시하고 반례 이것저것 넣고 assert 조지고 하느라 시도 횟수가 늘어났다.

아니 문제 알고리즘 바로 떠올리고 잘 풀어놓고 왜 구현에서 이상한 실수 하는지 모르겠는데 그냥 지금 졸려서 그렇다고 생각하자...

 

풀이 메모

더보기

disjoint set

각 사람이 다른 사람들에게 내야 하는 돈의 양을 저장해 두자
라고는 해도?
이거 어떻게 구현하지
뭔가 정공법으로 자료구조 짜야될거 같은 듯한 그런 느낌

아 잠깐만
1->2 2->3 같이 송금하는게 가능하잖아?
지출 금액을 생각하면

(지출 금액 - 빚진 금액(자기에게 빚진것도 포함))을 저장하자

가령 예제의 경우,
1: 20 / 2: -31 / 3: 11

2가 1에게 20, 2가 3에게 11 주면 그냥 되잖아

근데 해당 그래프에 있는 모든 사람들에게 적용하는거?
합쳐질때 넣으면 됨
그니까 한 그래프의 루트에 (또는 그냥 구조체 만들어서) 박은 다음에
합쳐지기 전에 나눠주자


그럼 그냥 나눠주는게 아니라 
sz 자체가 작은 쪽이 큰 쪽에 융화되면 될듯?

그니까 노드 개수가 적으면 

노드에 각자가 지출한 금액을 넣어두고, 각 그래프에 대해 각자가 지출한 금액의 값의 합을 저장하자
나중에 계산할때는 각 그래프에 대해 (그래프 총 지출금 / 그래프 크기)만큼 내야 하는 돈을 추가해 준다.

크기가 작은 쪽이 큰 쪽과 융합될 때, (큰 지출금 / 큰 크기)
?
융합되면 그냥 똑같나?
그건 아니네
어차피 나중에 total 값을 저장할거니까
작은 그래프 청산 하고나서 큰 그래프에 넣어주자

가령
   40            24
4 8 12 16    10 14
라고 한다면
24 / 10 14 그래프를 먼저 조져서 total값에 각각 10-12, 14-12 값을 더해주고
노드값을 40/4=10으로 초기화해준 다음에 total값은 40/4*2만큼 늘려준다.

disjoint set을 구현하면서 size를 넣어주고,
해당 disjoint set에 들어 있는 노드들을 저장해 주고
ㅇㅋ
ㄱㄱ'

잠깐!

노드값들은 그냥 tot값에만 저장하고
sum 만 더해주면 나중에 문제 없다
그니까 tot 이 10, 14일때, 24/2를 빼고 40/4를 더해주자.

-20 -5 10 15

ㅇㅎ..

그냥 1번이 총무 하자 ㅋㅋ

5 7
1 2 3
1 4 5
2 2 2
2 3 2
2 4 6
2 5 6
1 1 5

220825 문제 풀이 기록

2022. 8. 25. 23:16

G5 | 14699 - 관악산 등반

걸린 시간: 약 15분 (부정확)

체감 난이도: G5 ~ G4 사이 그 어딘가 애매한 지점

시도 횟수: 1회

풀이 쓸 의향: 下

풀이:

더보기

높이 있는 노드부터 차례대로 내려오면서 최대값 저장하기.

여담: 친구가 암만봐도 골드 5 아닌것같다고 해서 풀어본 문제.

솔직히 아이디어 자체는 G5가 맞는데 그래프기도 하고 이런저런 구현방법 잘 모르면 시간 끌릴수도 있겠다 싶어서 G4로 난이도 기여함.

 

 

P5 | 2463 - 비용

걸린 시간: 45분

체감 난이도: P4 하위권

시도 횟수: 2회

풀이 쓸 의향: 中

풀이:

더보기

비용 큰 간선부터 차례대로 간선 연결하면서, disjoint set으로 간선이 연결하는 그래프의 크기 고려하면서 정답값 더해주기.

여담: disjoint set 구현할 때 두 root값(그래프 크기값)을 곱하는 부분이 있었는데, root값을 int로 둬서 한번 틀림.

솔직히 처음 봤을때 바로 MST(Maximum)이 떠올랐는데, 실상 풀이는 MST를 안쓰는게 더 편해서 오히려 생각이 더 꼬였던 것 같다.

(풀이 메모)

더보기

가중치가 가장 작은 / 큰 간선은 몇 번 제거될까

작은 간선들을 보면?
가령 가중치가 2인 간선은 그냥 뭘 해도 다 없어지네?
!
MST
MST...가 맞나
Maximum?
Maximum spanning tree를 구성하자.

그럼 예제 그래프에서 남는 간선들이?
15 10 6 5 4가 된다
제거되는건 2, 3 <-- 얘들은 모든 두 정점 (u, v)에 대해 그냥 계속 없어지니까, N(N-1)/2번 없어진다
이제 작은것부터 보자
4도 뭘 해도 끊어진다
5는? (4 끊을때 5번 노드가 끊기므로) 5번 노드가 들어간 거 빼고는 다 끊어진다
6은? (5 끊을때 4번 노드가 끊기므로) 4번 노드가 들어간 거 빼고는 다 끊어진다
10은? (6 끊을때 그래프가 1-2, 3-6으로 나뉘므로) 


그래프가 나뉘는데, 각 그래프의 크기에 대해
어떤 한 그래프에서 다른 그래프로 연결하는 개수만큼..? 쫌 복잡하네요,,, 으엑

(1, 2) : 10 이하 다 끊김
(1, 6) : 6 이하 다 끊김
(1, 3) : 6 이하 다 끊김
근데 이렇게하면... N^2이잖아...

모든 그래프에서, 각 그래프 크기를 x라 하면,
sum(x(x-1)/2);
이게 깔끔하네
4:15
5:10
6:6
10:2
15:1

9*15 + 50 + 36 + 20 + 15



근데 구현을 어케함 이걸
uf 쓰기 싫은데
아니 uf 써도 시간 안에 되나
끊는거보단 잇는게 쉬우니깐...
큰거부터 이어볼까

!!

큰거부터 이어서 조지자
연결됐을 때, (x + = sz[s]*sz[e]), ans += v[node] * x;

ㄱㄱㄱㄱㄱㄱ
근데.. 그럼 사실 MST 필요없는거 아닌가
으익..!!!!
이미 연결되어 있었다면 x 증가 안시키고, 연결 안되어있었을 때만 증가시키게 하면 될듯
ㄱㄱ

220824 문제 풀이 기록

2022. 8. 24. 22:36

P4 | 1280 - 나무 심기

걸린 시간: 약 40분 (부정확)

체감 난이도: P5 상위권

시도 횟수: 3회

풀이 쓸 의향: 下

풀이

더보기

세그트리에 값 하나가 아니라 두개를 넣거나 두개의 세그트리를 따로 만들어서 값을 구하면 되는 문제.

여담: 

나머지 연산 실수때문에 한 번, 값 범위가 0부터 시작인거 못봐서 한 번 틀렸다.

 

 

P5 | 14572 - 스터디 그룹

걸린 시간: 약 30분

체감 난이도: P5 하위권

시도 횟수: 1회

풀이 쓸 의향: 下

풀이

더보기

실력 차이가 D 이하인 가장 큰 구간을 투 포인터로 구하고 나서 그 안에 사람들 죄다 돌려보며 구하기

여담: vector<pair<int, vector<int>>>라는 괴상한 자료구조를 만들어서 풀었다.

실력 차이가 D 이하인 모든 구간에서 최대한 많은 사람을 넣도록 투포인터로 풀린다는 아이디어가 쉬운 사람한테는 너무 쉽고, 어려운 사람한테는 너무 어렵게 보일만 한듯.

 

 

P3 | 10542 - 마피아 게임

걸린 시간: 1시간 10분

체감 난이도: P3

시도 횟수: 8회

풀이 쓸 의향: 上

풀이

더보기

문제 상황을 그래프로 추상화한 뒤에 관찰을 통해 terminal node를 고르는 것이 최적이라고 증명한 뒤 나머지 남은 cycle은 dfs 돌리면서 size/2만큼씩 더해준다.

여담: 정말 재밌게 푼 문제.

중간에 많이 해메서 좀 코드가 많이 더럽다. 남은 cycle 처리를 이상하게 해서 자꾸 틀리다 결국 발견해서 풀었다.

 

(풀이 메모)

더보기

서로 지목하지 않은 사람의 최대 수
그래프로 생각하면

어떤 그룹이 있을 때, 해당 그룹끼리는 서로 화살표가 연결되어있지 않은 최대 크기의 그룹?

1->3
2->3
3->4
4->5
5->6
6->4
7->4

?
노드 N개, 간선 N개인 그래프
사실 유향 그래프일 필요가 없는게 연결되어 있으면 절대 서로가 마피아가 아님.
홀짝놀이

노드 N개, 간선 N개인 무향 그래프에서 서로 이웃하지 않은 노드들의 최대 갯수

간선 N개인게 많이 중요할까
읆...

dfs dp로 되나

cycle 하나 떼면 트리인데...

dp[x][0] : x번 노드가 마피아가 아닐 때, dp[x][1] : x번 노드가 마피아일때 
쩝,,


연결된 개수가 작은걸 제일 먼저 고르는게 무조건 낫나?
그니까 어떤 노드를 고르면 연결된 다른 노드를 절대 고를 수 없는데, 어떤 노드를 고르지 않으면 다른 노드를 고를 수 있는 가능성이 생긴다
가령 1-3 끊으면 1, 3 disable, 2:0, 4:3
2


간선 N개니까 시간 안에 됨
제일 작은거부터 고르되, 제일 작은게 누구인지 계속 봐줘야됨



이거 뭔가 증명이 안되는데...
!
terminal을 고르는 것이 무조건 best이다
그럼 계속 terminal을 찾아서 제거하자

 

 

사실 입대 이후 거의 매일 문제를 한두문제씩은 풀고 있는데, [백준 문제 풀이] 탭에 글을 올릴 때는 꽤나 오랜 시간이 걸리기 때문에 2시간 남짓의 연등 시간동안 문제를 풀고 힌트와 풀이까지 작성하기에는 상당히 힘에 부쳤다.

사실 그래서 "와 이 문제 괜찮네... 블로그에 올려야겠다" 생각했던 문제들도 올리지 못하다가 풀이를 까먹어서 못올린 문제가 꽤 된다.

문제를 풀면서 배웠던 점들, 익혔던 점들을 기록하고 추후 풀이글 작성에 도움이 되고자 매일매일 풀었던 문제를 기록하고, 풀이 및 간단한 생각을 기록하고자 한다.

 

사실 필자가 문제를 풀 때는 항상 메모장을 켜서 나 스스로의 대화를 하며 문제를 풀어나가는데, 아마 해당 메모장을 그대로 올린 뒤에 풀이를 대충 기록하는 방식으로 진행할 것 같다.

"나 스스로의 대화"가 뭔지는 다음 글을 보면 뭔 소리인지는 대충 알 수 있겠지만, 필자는 문제를 풀 때 생각났던 풀이들과 생각들을 모두 메모장에 기록하면서 문제를 푼다.

그 생각이 틀린것 같아도 나중에 지우지는 않는데, 틀린 생각인줄 알았다가 나중에 다시 생각해보니 방향성은 맞았던 경우가 한둘이 아니라 너무 멀리 딴 길로 새주는 것을 막아주는, 일종의 방파제 역할을 해 주기 때문이다.

따라서 해당 기록을 보다 보면 내가 어떤 생각으로 문제를 풀었는지가 적나라하게 드러나고, 그만큼 더 복기하기 쉬워서 상당히 괜찮은 습관이라고 스스로 생각하고 있다.

다만 문제를 풀다가 미쳐버려서 욕지거리를 쓰기도 하는데... 그것도 내가 얼마나 고민했는지 알려주는 일종의 표시가 되니까 그냥 남겨 둘 생각이다.

 

문제 풀이 기록장에는 딱히 템플릿은 없을 것 같은데, 그냥 간단하게 문제 번호 / 링크 / 풀게 된 계기 (랜덤디펜스, 특정 알고리즘 학습 등) 따위를 적은 뒤에 걸린 시간, 시도 횟수, 메모장 내용 복붙 및 여담 작성으로 이루어질 것 같다.

백준 문제만 아니라 가끔 코드포스 문제나 기타 대회 문제들을 올리기도 할 것 같다.

1일 1글 작성... 어쩌면 가능할지도??!

'PS > 풀이 기록장' 카테고리의 다른 글

220828 문제 풀이 기록  (0) 2022.08.28
220827 문제 풀이 기록  (0) 2022.08.27
220826 문제 풀이 기록  (0) 2022.08.27
220825 문제 풀이 기록  (0) 2022.08.25
220824 문제 풀이 기록  (0) 2022.08.24

+ Recent posts