[BOJ] 정렬

Wonjun·2022년 7월 7일
0

BOJ

목록 보기
5/16
post-thumbnail

📝1427번: 소트 인사이드

문제 설명

소트 인사이트

해결 방법

1. 입력받은 숫자 N의 자릿수를 나눠서 num 배열에 넣는다.
2. num 배열을 sort 함수를 사용하여 내림차순 정렬한다.
3. num 배열을 출력해준다.

💻소스코드

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

int main() 
{
    int N;
    vector<int> num;
    cin >> N;
    while (N) {
        num.push_back(N % 10);
        N /= 10;
    }
    sort(num.begin(), num.end(), greater<int>());
    for (int i : num)
        cout << i;
        
    return 0;
}

📝2108번: 통계학

문제 설명

통계학

해결 방법

N개의 수를 입력받는다.
1. 산술평균 : N개의 수들의 합을 N으로 나눈 값
2. 중앙값 : N개의 수들을 증가하는 순서로 나열했을 경우 그 중앙에 위치하는 값
3. 최빈값 : N개의 수들 중 가장 많이 나타나는 값
4. 범위 : N개의 수들 중 최댓값과 최솟값의 차이

1) N개의 수를 입력받아 arr 배열에 push_back하고 합sum을 구해서 N으로 나눈 값을 출력한다(형변환 필수). 예외조건으로 -0 표현은 틀리다고 했으므로 -0.5보다 크고 0보다 작을 경우에는 0을 출력하도록 한다.
2) arr 배열을 sort 함수로 오름차순 정렬하고, N이 홀수라 하였으므로 arr 배열의 가운데에 위치한 원소를 출력한다.
3) 입력되는 정수의 절댓값이 4000을 넘지 않는다고 하였으므로 정수의 범위는 -4000 ~ 4000이다. 최빈값을 구하기 위해서 cnt 배열을 따로 선언하고 0으로 초기화하며, 크기는 8001로 한다. arr 배열에 정수 N을 push_back할 때 각 정수에 해당하는 배열 인덱스를 증가시켜준다. 정수 -4000의 개수는 cnt[0], -3999의 개수는 cnt[1], ... , 4000의 개수는 cnt[8000]에 들어있다. cnt 배열의 원소들을 비교해서 가장 큰 값이 최빈값이므로 출력한다.
4) arr 배열이 오름차순 정렬된 상태이므로, 맨 뒤의 원소에서 맨 앞의 원소를 뺀 값을 출력한다.

💻소스코드

#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
using namespace std;

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    vector<int> arr;
    int cnt[8001] = { 0 };
    int N, tmp, most_val;
    int sum = 0, most = -1;
    bool second = false;    
    cin >> N;
    for (int i = 0; i < N; i++) {
        cin >> tmp;
        arr.push_back(tmp);
        sum += tmp;
        cnt[arr[i] + 4000]++;
    }
    sort(arr.begin(), arr.end());
    for (int i = 0; i < 8001; i++) {
        if (cnt[i] == 0)
            continue;
        if (cnt[i] == most) {
            if (second) {
                most_val = i - 4000;
                second = false;
            }
        }
        if (cnt[i] > most) {
            most = cnt[i];
            most_val = i - 4000;
            second = true;
        }
    }
    float result = (float)sum / N;
    if (result > -0.5 && result < 0)
        cout << 0 << "\n";
    else
        cout << round(result) << "\n";  // 산술평균
    cout << arr[N / 2] << "\n";    // 중앙값
    cout << most_val << "\n";   // 최빈값
    cout << arr[arr.size() - 1] - arr[0] << "\n";   // 범위
    return 0;
}

📝11650번: 좌표 정렬하기

문제 설명

좌표 정렬하기

해결 방법

N개의 좌표 (x, y)를 입력받아 x값을 기준으로 우선 오름차순 정렬 후, x 값이 같으면 y 기준으로 오름차순 정렬한다. sort 함수와 pair를 이용해서 간단하게 코드를 작성할 수 있다. cmp 함수는 pair의 first가 같으면 second를 비교해서 오름차순 정렬하도록 했고, 같지 않다면 first 기준으로 오름차순 정렬하게 된다. cmp 함수는 따로 구현할 필요가 없다. sort 함수가 first 요소를 먼저 정렬하고, first 요소가 같다면 second 요소를 정렬하기 때문이다.

💻소스코드

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

bool cmp(pair<int, int> a, pair<int, int> b) {
    if (a.first == b.first)
        return a.second < b.second;
    return a.first < b.first;
}

int main() 
{
    int N;
    int x, y;
    vector<pair<int, int>> num;
    cin >> N;
    for (int i = 0; i < N; i++) {
        cin >> x >> y;
        num.push_back({x, y});
    }
    sort(num.begin(), num.end(), cmp);
    for (auto n : num)
        cout << n.first << " " << n.second << "\n";
    return 0;
}

📝1181번: 단어 정렬

문제 설명

단어 정렬

해결 방법

N개의 단어를 입력받아서 vector<string> words에 push_back 한다. sort 함수에 커스터마이징 한 cmp 함수를 인자로 받아서 길이 순으로 오름차순 정렬하되, 길이가 같으면 사전 순으로 정렬하도록 했다. 문제 조건에서 같은 단어는 출력하지 말라고 하였으므로, unique 함수를 써서 중복되는 원소들은 제거한 후 출력했다.

💻소스코드

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

bool cmp(string a, string b) {
    if (a.size() == b.size())
        return a < b;
    return a.size() < b.size();
}

int main() 
{
    int N;
    string str;
    vector<string> words;
    cin >> N;
    for (int i = 0; i < N; i++) {
        cin >> str;
        words.push_back(str);
    }
    sort(words.begin(), words.end(), cmp);
    words.erase(unique(words.begin(), words.end()), words.end());
    for (auto n : words)
        cout << n << "\n";
    return 0;
}

📝10814번: 나이순 정렬

문제 설명

나이순 정렬

해결 방법

stable_sort() 함수를 사용하면 안정 정렬이 이루어진다. 안정 정렬이란, 같은 값을 가지는 원소에 대해 위치 변동이 없는 것이다. 나이순으로 오름차순 정렬을 해주고, 나이가 같으면 가입한 순서대로 정렬을 해야하므로 입력 순서대로 정렬이 되어야 한다.

💻소스코드

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

bool cmp(pair<int, string> a, pair<int, string> b) {
    return a.first < b.first;
}

int main() 
{
    int N;
    int age;
    string name;
    vector<pair<int, string>> v;
    cin >> N;
    for (int i = 0; i < N; i++) {
        cin >> age >> name;
        v.push_back({age, name});
    }
    stable_sort(v.begin(), v.end(), cmp);
    for (auto n : v)
        cout << n.first << " " << n.second << "\n";
    return 0;
}

📝18870번: 좌표 압축

문제 설명

좌표 압축

해결 방법

lower_bound()와 unique() 함수를 사용하면 간결한 코드로 문제를 해결할 수 있지만, 두 함수를 사용하지 않고 해결해보았다. 시간초과가 났다. 써야겠다.
1. 초기 입력을 유지할 origin 벡터와 sort 함수 사용으로 원소를 정렬할 copy 벡터를 선언하고 입력 값을 push_back 한다.
2. 원소의 순위(크기 순서)와 값을 대응시킬 각각의 p_origin, p_copy 벡터를 선언한다. p_copy 벡터의 first에 정렬된 copy 벡터 각각의 원소 값에 해당하는 순위cnt를, second에 copy 벡터의 원소copy[i]를 push_back 한다.
3. 이중 for문을 사용해서 origin 벡터에 있는 원소와 p_copy 벡터의 second 가 같으면 p_origin의 first에 순위p_copy[j].first, second에 값orgin[i]을 push_back 하고 p_orgin의 first 값들을 참조하여 출력한다.

  • lower_bound()와 unique() 함수를 사용
  1. 원본 벡터와 복사본 벡터를 선언하고 입력값을 넣는다.
  2. 복사본 벡터를 오름차순 정렬하고, unique와 erase를 사용해서 중복되지 않은 원소들만 남긴다.
  3. lower_bound를 사용해서 원본 벡터의 i 번째 원소가 복사본 벡터에서 몇번째에 위치 하는지 출력한다. lower_bound는 반복자를 반환하므로 copy.begin()을 빼서 인덱스를 구할 수 있다.

💻소스코드

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

int main() 
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    int N, num;
    cin >> N;
    vector<int> copy, origin;
    for (int i = 0; i < N; i++) {
        cin >> num;
        copy.push_back(num);
        origin.push_back(num);
    }
    sort(copy.begin(), copy.end());
    copy.erase(unique(copy.begin(), copy.end()), copy.end());
    for (int i = 0; i < N; i++) {
        cout << lower_bound(copy.begin(), copy.end(), origin[i]) - copy.begin() << " ";
    }
    return 0;
}

profile
성장 = 학습 + 적용 + 회고

0개의 댓글