Programming

[BOJ 25577] 열 정렬정렬 정

minigb 2023. 9. 27. 01:00

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

 

25577번: 열 정렬정렬 정

첫 번째 줄에 배열의 크기 $N(4 ≤ N​ ≤ 100\,000)$이 주어진다. 그다음 줄에 배열의 원소 $A_1, A_2, \cdots, A_n (-10^9 ≤ A_i ≤ 10^9, i \neq j $ 이면 $ A_i \neq A_j )$ 이 주어진다. 배열의 원소는 모두 정수이다

www.acmicpc.net

 

하나의 예를 살펴보자.

 

1 7 2 9 3 8 0

 

이것은 이렇게 정렬되어야 한다.

 

0 1 2 3 7 8 9

 

1이 있는 자리에 0이 있어야 하고, 0이 있는 자리에 9가 있어야 하고, 9가 있는 자리에 3이 있어야 하고, … 그렇다.

 

그러므로 여기서 현재의 상태와, 이것이 어떻게 바뀌어야 하는지 간의 관계에 대한 그래프를 만든다.

각 위치의 (현재 수) -> (원래 그 자리에 있어야 하는 수)들을 edge로 만든다.

여기서는 1->0, 7->1, 2->2, 9->3, 3->7, 8->8, 0->9이다. 

 

그리고 이 그래프에서의 cycle을 찾는다.

1 -> 0 -> 9 -> 3 -> 7 -> 1

2 -> 2

8 -> 8

답은 (cycle의 길이 - 1)의 합.

int main() {
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    int n; cin >> n;
    vector<int> arr(n);
    for (int i = 0; i < n; ++i) {
        cin >> arr[i];
    }
    vector<int> arr_sorted = arr;
    sort(arr_sorted.begin(), arr_sorted.end());
    
    unordered_map<int, int> mp;
    for (int i = 0; i < n; ++i) {
        mp[arr_sorted[i]] = i;
    }
    for (int i = 0; i < n; ++i) {
        arr[i] = mp[arr[i]];
    }

    int ans = 0;
    vector<bool> visited(n, false);
    for (int i = 0; i < n; ++i) {
        if (visited[i]) {
            continue;
        }

        int cycle_len = 0;
        int cur = i;
        while (!visited[cur]) {
            visited[cur] = true;
            ++cycle_len;
            cur = arr[cur];
        }
        ans += cycle_len - 1;
    }

    cout << ans << kEndl;
}

 

재밌는 문제

 

앞으로는 스터디에서 푼 것들 다 그때그때 풀어둬야겠다. 지난주에 푼 것도 재밌었는데 나중에 풀어야겠다- 하고서는 넘어갔더니 잊어버려서 복기하려면 시간이 걸릴 거 같다.

 

근데 다음 스터디는 무려 10/31이다 ㅋㅋ

 

이렇게 가늘고 길게 가길!

 

 

 

 

 

 

 

https://blog.naver.com/mini_gb/223222623341

 

[BOJ 25577] 열 정렬정렬 정

https://www.acmicpc.net/problem/25577 하나의 예를 살펴보자. 1 7 2 9 3 8 0 이것은 이렇게 정렬되어야 ...

blog.naver.com