분류 전체보기

220903 문제 풀이 기록

2022. 9. 4. 01:15

오늘은 G5~G1 랜덤 디펜스를 해봤다.

원래 순서대로 푸려고 했는데, G4랑 G2 라인 문제가 잘 안떠올라서 G5-G3-G4-G1-G2 순으로 풀렸다.

 

 

총 풀이 시간: 약 2시간 20분

 

G5 | 12887 - 경로 게임

시도 횟수: 1회

체감 난이도: G5

풀이 쓸 의향: 下

풀이

더보기

단순 BFS문제. 가장 빠르게 도착했을 때 거치는 블럭 개수를 총 하얀 블럭 개수에서 빼주면 된다.

여담: 여기까지는 10분컷이었는데,,, :(

 

 

 

G3 | 19535 - ㄷㄷㄷㅈ

시도 횟수: 2회

체감 난이도: G3~G2 사이 어딘가

풀이 쓸 의향: 中

풀이

더보기

간선 개수가 3 이상인 노드에 대해서 "ㅈ" 그래프는 XC3개이고, "ㄷ" 그래프는 간선이 2개인 노드들에 인접한 다른 노드에 연결된 간선 개수 + 간선이 3개 이상인 노드들에 인접한 다른 노드에 연결된 간선 개수 * (현재 간선-1) 에 2를 나눠주자.

여담: DFS / BFS 문제인줄 알았는데 무조건 시간초과 난다는 것을 깨닫고 후다닥 풀이를 틀어버린 문제. 상당히 흥미로운 문제였다.

 

 

 

G4 | 25307 - 시루의 백화점 구경

시도 횟수: 3회

체감 난이도: G3

풀이 쓸 의향: 下

풀이

더보기

마네킹에서 BFS, 출발지점에서 BFS 돌려서 총 2회 돌리기, 근데 최적화 제대로 안하면 터짐

여담: 최적화를 제대로 안해서 한 번, 그냥 급하게 내다가 한 번 더 틀렸다. 원래 이렇게 오래 걸릴 문제는 아니었는데 마네킹에서 BFS를 돌릴 때 최적화하는 방법이 뭔가 머리에서 안떠올랐다. 피곤한 날엔 코딩하지 말아야지...

 

 

 

G1 | 21320 - 순간이동 여행

시도 횟수: 1회

체감 난이도: G1

풀이 쓸 의향: 中

풀이

더보기

어디에서 시작하든 반드시 루트 노드로 갔다가 반대쪽으로 가는 것이 최적임을 파악한 뒤, 각 트리의 높이에 따른 순간이동 최소 횟수를 dp 점화식으로 나타내어 해결하기

여담: 풀이가 꽤 재밌고 dp 점화식 구하는 과정이 흥미로웠다.

 

 

 

G2 | 1797 - 균형잡힌 줄서기

시도 횟수: 2회

체감 난이도: G2

풀이 쓸 의향: 下

풀이

더보기

남자를 -1, 여자를 1로 바꾼 뒤 부분합 처리한 뒤, i=0부터 n까지 가장 왼쪽에 있는 동일한 부분합 인덱스값 확인하면서 v[i]에서 끝나는 구간에서의 정답 구하기

여담: 처음에 prefix sum이라고 잘 생각했다가 갑자기 턱 막혀서 위의 G1 문제로 넘어갔었다.

DP로 해결되지 않을까 하는 마음에 DP 점화식을 세워보려던게 패착이었던 것 같은데, 사실 이 문제에서 prefix sum을 안쓰면 딱히 할 수 있는게 없어 보였음에도 부분합 풀이를 치워두고 DP 풀이로는 왜 갔던걸까....

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

220905 문제 풀이 기록  (0) 2022.09.05
220904 문제 풀이 기록  (0) 2022.09.04
220902 문제 풀이 기록  (0) 2022.09.04
220901 문제 풀이 기록  (0) 2022.09.01
220831 문제 풀이 기록  (0) 2022.08.31

220902 문제 풀이 기록

2022. 9. 4. 01:02

P4 | 17408 - 수열과 쿼리 24

풀이 시간: 약 25분

시도 횟수: 4회

체감 난이도: P4 날먹

풀이 쓸 의향: 下

풀이

더보기

그냥 세그트리 연습문제

여담: 이날 코포치느라 글도 못쓰고 문제도 별로 못풀었는데, 코포도 조져서 슬프다,,, :(

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

220904 문제 풀이 기록  (0) 2022.09.04
220903 문제 풀이 기록  (0) 2022.09.04
220901 문제 풀이 기록  (0) 2022.09.01
220831 문제 풀이 기록  (0) 2022.08.31
220830 문제 풀이 기록  (0) 2022.08.30

220901 문제 풀이 기록

2022. 9. 1. 23:34

G3 | 11562 - 백양로 브레이크

풀이 시간: 약 25분

시도 횟수: 2회

체감 난이도: G3

풀이 쓸 의향: 下

풀이

더보기

모든 노드에서 다른 모든 노드까지 다익스트라 돌리기. 플로이드-워셜도 됨.

여담: 그냥 문득 G3이 어느 정도 난이도였나 기억하려고 한번 풀어봄.

 

 

P5 | 20158 - 사장님 달려가고 있습니다

풀이 시간: 약 1시간 + 20분

시도 횟수: 무려!!! 14회

체감 난이도: 마음같아선 P4주고싶지만 내실수로 이렇게된거라 P5 하위권...

풀이 쓸 의향: 下

풀이

더보기

그냥 단순 BFS인데 구현량이 좀 많음

여담: 이틀 전에 풀다가 때려치고 다시 풀었다. 참 많은 곳에서 실수를 해버려서... ;(

달려가는 중간에 있는 구역도 장애물이 있으면 밟으면 안된다는 점에 주의할 것....

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

220903 문제 풀이 기록  (0) 2022.09.04
220902 문제 풀이 기록  (0) 2022.09.04
220831 문제 풀이 기록  (0) 2022.08.31
220830 문제 풀이 기록  (0) 2022.08.30
220829 문제 풀이 기록  (0) 2022.08.29

220831 문제 풀이 기록

2022. 8. 31. 23:52

P4 | 10220 - Self Representing Seq

풀이 시간: 약 25분 + 10분

시도 횟수: 2회

체감 난이도: X

풀이 쓸 의향: 下

풀이

더보기

N<=3 이거나 N==6이면 0, N==4면 2, 나머진 모두 1 출력.

여담: 사실 N=1부터 N=16쯤까지 브루트 포스로 한번 다 해보니까 이상한 규칙이 보이길래 일단 때려박아보고 AC 맞은 뒤에 증명함...

태그에 "런타임 전의 전처리" 박으려다가 꾹 참고 그냥 뒀는데, 증명 후 풀이였으면 정말 P3 위로 올라가는 정신나간 난이도의 문제였을 것으로 추정됨.

 

 

사실 더 풀려고 했는데 문제 하나 잘못 읽고 삽질하는 바람에 나중에 푸는 걸로.... ;(

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

220902 문제 풀이 기록  (0) 2022.09.04
220901 문제 풀이 기록  (0) 2022.09.01
220830 문제 풀이 기록  (0) 2022.08.30
220829 문제 풀이 기록  (0) 2022.08.29
220828 문제 풀이 기록  (0) 2022.08.28

220830 문제 풀이 기록

2022. 8. 30. 23:48

P4 | 1412 - 일방통행

풀이 시간: 약 40분

시도 횟수: 2회

체감 난이도: P4 최하위권

풀이 쓸 의향: 中

풀이

더보기

주어진 그래프에서 일방통행 도로들만 봤을 때, 사이클이 있으면 NO, 없으면 YES

여담: 이 아이디어가 굉장히 빨리 떠올라서 운 좋게 빠르게 풀 수 있었다. 만약 이 아이디어 상상이 안됐다면, 혹은 관찰 첫발을 잘못 밟았으면 충분히 높은 난이도라고 생각될 수 있겠다 싶다.

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

220901 문제 풀이 기록  (0) 2022.09.01
220831 문제 풀이 기록  (0) 2022.08.31
220829 문제 풀이 기록  (0) 2022.08.29
220828 문제 풀이 기록  (0) 2022.08.28
220827 문제 풀이 기록  (0) 2022.08.27

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

 

10542번: 마피아 게임

초등학교에서도 중학교에서도 고등학교에서도 대학교에서도 소풍에서도 엠티에서도 낮이나 밤이나 봄이나 여름이나 가을이나 겨울이나 실내에서도 실외에서도 손쉽게 즐길 수 있는 마.피.아.

www.acmicpc.net

 

1. 문제

- $N$명의 사람들이 마피아 게임을 진행한다.

- 각 사람들이 마피아일것 같은 사람을 투표하게 되는데, 시민은 자신을 제외한 다른 사람 아무나 투표하고, 마피아는 시민 중 한 명에게 투표한다.

- 마피아일 수 있는 사람 수의 최대값을 출력하라.

 

2. 힌트

 

힌트 1

더보기

문제 자체만으로 풀기에는 너무 까다로우니, 일단 유향 그래프로 문제 상황을 정리해서 생각해 보자.

a가 b에게 투표했으면 a->b로 나타내는 방식으로 하면 문제 상황을 쉽게 정리할 수 있을 것이다.

 

힌트 2

더보기

사실 유향 그래프가 아니라 무향 그래프로도 충분히 문제를 해결할 수 있다.

a가 b에게 투표를 했건, b가 a에게 투표를 했건 두 사람이 동시에 마피아일 수는 없기 때문이다.

이제 문제가 "그래프에서 이웃하지 않은 정점들을 고르는 최대 개수를 구하시오" 로 바뀌었다.

 

힌트 3

더보기

만약 트리가 1-2-3 처럼 한 줄로 되어 있고, 1번, 2번 노드가 단말 노드라면 2번 노드를 고르는 것 보다는 1번 노드를 고르는 것이 반드시 최적이다.

이를 조금 확장해서 생각해 보자. 반드시 a를 고르는것보다 b를 고르는 경우가 더욱 이득인 경우는 어떤 경우일까?

 

 

3. 문제 관찰 과정 및 풀이

 

3-1. 문제 관찰 과정

문제를 처음 봤을 때, 솔직히 조금 어지러웠다. 문제 지문이 살짝 이해하기 힘든 점도 있기는 했지만, 그보다도 대체 문제 풀이를 어떻게 시작해야 할지 감도 안잡혔기 때문이다.

조금 생각하다 보니, 참가자의 투표를 유향 그래프로 나타내어 그래프를 직접 그려보면 문제 상황 자체를 쉽게 이해할 수 있다 생각이 들어 그림판을 켜서 예제 입력을 직접 그리며 관찰해 보았다.

 

"마피아는 서로 마피아를 투표하지 않는다" 라는 것은, 그래프가 a->b로 연결되어 있을 때 a번 사람이 마피아라면 b번 사람은 마피아일 수 없다는 것을 의미한다.

그런데, 어차피 a->b로 연결되어 a번 사람과 b번 사람이 동시에 마피아가 될 수 없다면 그래프를 유향 그래프로 그리는 것이 오히려 불편해지기 때문에, 무향 그래프로 바꾸어 생각해 보았다.

 

이렇게 무향 그래프로 바꾸고 나면 "서로 이웃하지 않는 노드들을 최대한 많이 선택할 때, 그 노드들의 개수를 구하여라" 라고 문제를 변환하여 생각할 수 있다.

처음에는 DP 문제일까 하고 고민해 보았는데, 어떻게 구현해도 시간 안에 예쁘게 구현될 것 같지 않아서 때려쳤다.

 

그렇게 계속 관찰하다가, "일단 반드시 골랐을 때 이득인 노드가 있을까?" 라는 생각으로 그래프를 살펴보았다.

가장 처음에는 연결된 개수가 가장 작은 것을 먼저 고르면 되는 그리디 문제인가 고민해 보았지만, 바로 반례를 찾아 폐기되었다.

그런데 반례를 만들다가 a->b->c로 일직선으로 (즉, 옆으로 새는 길 없이) 연결된 형태이며 a, b번 노드가 둘 다 단말 노드라면 b보다는 a를 고르는 것이 최적이라는 사실을 발견했다.

이를 조금 더 확장하여 문제를 해결해 보자.

 

3-2. 문제 풀이

각 정점을 사람의 번호, 간선은 서로가 투표했는지 여부에 따라 무향 그래프를 하나 생성한다.

그렇다면 문제가 "서로 이웃하지 않는 노드들을 최대한 많이 선택할 때, 그 노드들의 개수를 구하여라" 로 치환된다.

 

이 때, 반드시 단말 노드를 가장 먼저 고르는 것이 최적이라는 사실을 관찰을 통해 짐작할 수 있다.

이유는 간단한데, 단말 노드의 경우 간선이 단 하나만 연결되어 있으므로 해당 노드를 골랐을 때 고르지 못하게 되는 노드는 단 하나만 생긴다.

그런데 단말 노드 대신 고르지 못하게 되는 다른 노드를 고르게 되면 반드시 단말 노드를 고른 것보다 고를 수 있는 노드 수가 항상 같거나 적으므로, 단말 노드를 고르는 것이 더 최적해라는 것을 알 수 있다.

 

또한, 단말 노드가 존재하지 않을 때까지 노드를 고르면 나머지 그래프들은 전부 거대한 사이클 하나로 이루어진 그래프가 되는데, 사이클 하나로 이루어진 그래프에서는 반드시 (노드 개수 / 2) 만큼의 노드를 고를 수 있으니 각 사이클을 DFS로 돌며 크기를 확인하고 값을 더해주면 된다.

 

주의할 점은, 이 문제의 경우 그래프 하나가 아니라 끊어져 있는 서로 다른 여러 그래프가 나올 수 있으므로 사이클 크기 처리를 해 줄때 각 그래프에 대해 한 번씩 전부 돌며 연산해주어야 한다.

 

4. 코드

너무 신난 상태로 코드를 짜서 그런지 코드가 많이 더럽다.

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;

vector<int> visited;
vector<vector<int>> v;

int dfs(int node, int x) {
    visited[node] = 1;
    for (int i=0; i<v[node].size(); i++) {
        if (visited[v[node][i]])    continue;
        return dfs(v[node][i], x+1);
    }
    return x;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(NULL);  cout.tie(NULL);
    int n;
    int a[500005];
    int cnt[500005];
    int ans = 0;
    memset(cnt, 0, sizeof(cnt));
    cin >> n;
    
    v = vector<vector<int>>(n+1);
    visited = vector<int>(n+1, 0);
    
    for (int i=1; i<=n; i++) {
        cin >> a[i];
        if (a[i] < i && a[a[i]] == i) {	// 서로가 서로를 지목한 경우;
            continue;
        }
        v[i].push_back(a[i]);
        v[a[i]].push_back(i);
        cnt[a[i]]++;	// 연결된 간선 개수
        cnt[i]++;
    }
    
    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
    for (int i=1; i<=n; i++) {
        pq.push({cnt[i], i});
    }
    
    while (!pq.empty()) {
        int sz = pq.top().first;
        int node = pq.top().second;
        pq.pop();
        if (visited[node])  continue;
        if (sz>1)  break;
        
        ans++;
        visited[node] = 1;
        for (int i=0; i<v[node].size(); i++) {
            int nnode = v[node][i];
            if (visited[nnode]) continue;
            visited[nnode] = 1;
            for (int j=0; j<v[nnode].size(); j++) {
                if (visited[v[nnode][j]])   continue;
                cnt[v[nnode][j]]--;
                pq.push({cnt[v[nnode][j]], v[nnode][j]});
            }
        }
    }
    
    for (int i=0; i<n; i++) {
        if (visited[i]) continue;
        ans += dfs(i, 1) / 2;
    }
    
    cout << ans;
}

5. 여담

오랜만에 정말 마음에 드는 문제를 풀었다. 관찰 과정부터 풀이 구현까지 전부 즐겁게 해결한 문제.

태그 중에 분리 집합이 있는 것을 보아하니 분리 집합으로도 풀 수 있는 모양이다.

 

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

+ Recent posts