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

 

25305번: 커트라인

시험 응시자들 가운데 1등은 100점, 2등은 98점, 3등은 93점이다. 2등까지 상을 받으므로 커트라인은 98점이다.

www.acmicpc.net


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine()," ");

        int N = Integer.parseInt(st.nextToken());
        int K = Integer.parseInt(st.nextToken());
        int[] arr = new int[N];

        st = new StringTokenizer(br.readLine()," ");

        for(int i=0; i<N; i++){
            arr[i]=Integer.parseInt(st.nextToken());
        }
        int temp;
        for(int i=0; i<N-1; i++){
            for(int j=i+1; j<N; j++){
                if(arr[i]<arr[j]){
                    temp = arr[j];
                    arr[j]=arr[i];
                    arr[i]=temp;
                }
            }
        }

        System.out.println(arr[K-1]);
    }
}

해당 문제를 위의 코드로 풀었는데 정렬 알고리즘에 대한 개념이 제대로 박혀있지 않은 채 그냥 정렬을 시킨다는 것에 의의를 두고 푼 것 같아 7가지 정렬을 해당 문제로 정리해보려고 한다. 

 

1. 선택 정렬(selection sort)

  • 설명: 제자리 정렬 알고리즘의 하나로 각 순서에 원소를 넣을 위치는 이미 정해져 있고, 어떤 원소를 넣을지 선택하는 알고리즘이다.
  • 시간 복잡도: O(n^2)
  • 과정
    • 주어진 배열에서 최댓값을 찾은 다음 맨 앞에 위치한 값과 교체한다.
    • 맨 앞에 위치한 값을 제외한 배열에서 똑같은 과정을 반복한다. 
int temp, indexMax;
        for(int i=0; i<N-1; i++){
            indexMax=i;
            for(int j=i+1; j<N; j++){
               if(arr[j]>arr[indexMax]){
                   indexMax=j; }
            }
            temp = arr[indexMax];
            arr[indexMax]=arr[i];
            arr[i]=temp;
        }

indexMax라는 변수를 통하여 최대 값이 존재하는 인덱스를 찾아냈다. 이후 정렬의 끝까지 탐색이 끝난 후, indexMax의 값을 인덱스로 가진 값을 맨 앞의 위치에 옮긴다. 

2. 버블 정렬(bubble sort)

  • 설명: 선택정렬과 비슷한 알고리즘으로 인접한 두 요소의 대소를 비교해가며 자리를 교환하는 방식이다. 거품이 수면에 올라오는 것과 유사하다고 하여 붙여진 이름이다. 
  • 시간 복잡도: O(n^2) // 굉장히 비효율적이다. 
  • 과정
    • 처음부터 시작하여 인접한 두 원소의 대소를 비교한다. 배열의 끝까지 반복하면 제일 끝에 제일 큰/작은 원소가 위치하게 되므로 그다음과정에선 제일 끝의 원소를 제외한다.
  int temp;
        for(int i=0; i<N-1; i++){
            for(int j=i+1; j<N-1-i; j++){
                if(arr[j]<arr[j+1]){
                    temp=arr[j];
                    arr[j]=arr[j+1];
                    arr[j+1]=temp;
                }
            }
        }

 

3. 삽입 정렬(insertion sort)

  • 설명: 선택정렬과 비슷한 알고리즘으로 인접한 두 요소의 대소를 비교해가며 자리를 교환하는 방식이다. 거품이 수면에 올라오는 것과 유사하다고 하여 붙여진 이름이다. 
  • 시간 복잡도: O(n^2) // 굉장히 비효율적이다. 
  • 과정
    • 처음부터 시작하여 인접한 두 원소의 대소를 비교한다. 배열의 끝까지 반복하면 제일 끝에 제일 큰/작은 원소가 위치하게 되므로 그다음과정에선 제일 끝의 원소를 제외한다.

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

 

2750번: 수 정렬하기

첫째 줄에 수의 개수 N(1 ≤ N ≤ 1,000)이 주어진다. 둘째 줄부터 N개의 줄에는 수가 주어진다. 이 수는 절댓값이 1,000보다 작거나 같은 정수이다. 수는 중복되지 않는다.

www.acmicpc.net

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int num = Integer.parseInt(br.readLine());
        int[] arr = new int[num];

        for(int i=0; i<num; i++){
            arr[i]=Integer.parseInt(br.readLine());
        }

        insertion_sort(arr, num);
        for(int i=0;i<num;i++){
            System.out.println(arr[i]);
        }
    }

    private static void insertion_sort(int[] arr, int num){
        int key;
        for(int i=1; i<num; i++){
            key = arr[i];
            for(int j=i-1;j>=0 && arr[j]>key;j--){
                arr[j+1]= arr[j];
                arr[j]=key;
            }
        }
    }
}

 

4. 퀵 정렬(quick sort)

  • 설명
    • 이름과 같이 빠른 정렬이 특징인 정렬이며 제자리 정렬이다. 하나의 피벗을 기준으로 피벗보다 큰 원소들의 부분리스트, 피벗보다 작은 원소들의 부분리스트로 정렬한 후 각 부분리스트에서 다시 같은 과정을 반복한다.
    • 병합 정렬과의 차이점이 있다면 병합 정렬은 두 리스트의 크기가 균등하지만 퀵 정렬은 피봇값을 기준으로 나누어지기 때문에 균등하지 않을 수 있다. (=비균등하다.)
  • 시간 복잡도: 
  • 과정
    • 1. 리스트 안에 있는 원소중 하나(=피벗)를 고른다.
    • 2. 작은 요소들은 왼쪽으로, 큰 요소들은 오른쪽으로 옮긴다.
    • 3. 피벗을 제외한 왼쪽 리스트와 오른쪽 리스트를 순환호출을 통하여 같은 과정을 반복한다. 
    • 4. 부분리스트의 크기가 1이 아닐 때까지 반복한 후 인접한 리스트들끼리 합친다. 

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

 

2587번: 대표값2

어떤 수들이 있을 때, 그 수들을 대표하는 값으로 가장 흔하게 쓰이는 것은 평균이다. 평균은 주어진 모든 수의 합을 수의 개수로 나눈 것이다. 예를 들어 10, 40, 30, 60, 30의 평균은 (10 + 40 + 30 + 60 +

www.acmicpc.net

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {

    public static int[] sort(int[] arr){
        l_pivot_sort(arr,0,arr.length -1);
        return arr;
    }

    private static void l_pivot_sort(int[] arr, int lo, int hi){
        if(lo>=hi){
            return;
        }

        int pivot = partition(arr,lo,hi);

        l_pivot_sort(arr,lo,pivot-1);
        l_pivot_sort(arr,pivot+1,hi);
    }

    private static int partition(int[] arr, int left, int right){

        int lo = left;
        int hi = right;
        int pivot = arr[left];  //부분 리스트의 왼쪽 요소를 피벗으로 설정.

        //lo가 hi보다 작을 때 까지만 반복한다.
        while (lo<hi){

            while (arr[hi] > pivot && lo < hi) {
                hi--;
            }

            while (arr[lo]<=pivot && lo<hi){
                lo++;
            }

            swap(arr,lo,hi);
        }

        swap(arr, left, lo);
        return lo;
    }

    private static void swap(int[] arr, int i, int j){
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int sum=0;
        int[] arr = new int[5];
        for(int i=0;i<5;i++){
            arr[i]=Integer.parseInt(br.readLine());
            sum+=arr[i];
        }
        System.out.println(sum/5);  //평균값 출력

        sort(arr);
        int value = arr[2];
        System.out.println(value);
    }
}

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

 

10989번: 수 정렬하기 3

첫째 줄에 수의 개수 N(1 ≤ N ≤ 10,000,000)이 주어진다. 둘째 줄부터 N개의 줄에는 수가 주어진다. 이 수는 10,000보다 작거나 같은 자연수이다.

www.acmicpc.net

import javax.imageio.plugins.jpeg.JPEGImageReadParam;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        int num = Integer.parseInt(br.readLine());
        int[] arr = new int[num];
        for (int i = 0; i < num; i++) {
            arr[i] = Integer.parseInt(br.readLine());
        }
        quickSort(arr);
        for(int i=0;i<arr.length;i++){
            System.out.println(arr[i]);
        }
    }

    public static void quickSort(int[] arr) {
        quickSort(arr, 0, arr.length - 1);
    }

    private static void quickSort(int[] arr, int start, int end) {

        if (start >= end) {
            return;
        }

        int pivot = start;
        int lo = start + 1;
        int hi = end;

        while (lo <= hi) {
            while (lo <= end && arr[lo] <= arr[pivot])
                lo++;
            while (hi > start && arr[hi] > arr[pivot])
                hi--;
            if (lo > hi)
                swap(arr, hi, pivot);
            else
                swap(arr, lo, hi);

            quickSort(arr, start, hi - 1);
            quickSort(arr, hi + 1, end);
        }

    }
    private static void swap( int[] arr, int i, int j){
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
}

위 문제는 문제의 의도는 정렬 그 자체는 아니였지만 퀵 정렬이 헷갈려서 풀어보았다. 

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

 

1546번: 평균

첫째 줄에 시험 본 과목의 개수 N이 주어진다. 이 값은 1000보다 작거나 같다. 둘째 줄에 세준이의 현재 성적이 주어진다. 이 값은 100보다 작거나 같은 음이 아닌 정수이고, 적어도 하나의 값은 0보

www.acmicpc.net

import javax.swing.plaf.basic.BasicButtonUI;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int num = Integer.parseInt(br.readLine());
        double[] arr = new double[num];

        StringTokenizer st = new StringTokenizer(br.readLine()," ");

        for(int i=0;i<num;i++){
            arr[i]=Double.parseDouble(st.nextToken());
        }

        quickSort(arr);

        double hiScore=arr[num-1];
        double score=arr[num-1];


        for(int i=0;i<num-1;i++){
            arr[i]=arr[i]/hiScore*100;
            score+=arr[i];
            System.out.println(arr[i]);
        }
        System.out.println(arr[num-1]);
        System.out.println(score/num);
    }

    public static void quickSort(double[] arr){
        quickSort(arr, 0, arr.length-1);
    }

    private static void quickSort(double[] arr, int start, int end){

        if(start>end){
            return;
        }

        int pivot = start;
        int lo = start+1;
        int hi = end;

        while(lo<=hi){
            while(lo<=pivot && arr[lo]<=arr[pivot]){
                lo++;
            }
            while (hi>pivot && arr[hi]>=arr[pivot]){
                hi--;
            }
            if(lo>hi){
                swap(arr,hi,pivot);
            }
            else{
                swap(arr,lo,hi);
            }

            quickSort(arr,start,hi-1);
            quickSort(arr,hi+1,end);
        }


    }

    private static void swap(double[] arr, int a, int b){
        double temp = arr[a];
        arr[a] = arr[b];
        arr[b] = temp;
    }
}

이 문제도 마찬가지

'Algorithm' 카테고리의 다른 글

알고리즘 학습계획 수립  (0) 2023.10.04

+ Recent posts