본문 바로가기
백준/단계별

백준 11651 C#) 좌표 정렬하기 2

by alpacadabra 2022. 10. 12.

이전 문제처럼 ValueTuple을 사용해서 풀어보자.

 

*IComparable, IComparer에 대해 모른다면 이 글을 먼저 읽어보자.

 

비교-정렬을 위한 두 인터페이스, IComparable과 IComparer

IComparable 과 IComparer 는 비슷한 일을 하지만 근본적인 차이가 있다. 이 게시글에서는 두 인터페이스의 용도와 차이에 대해 알아볼 것이다. IComparable C#의 커스텀 클래스는 기본적으로 "비교 불가능

sete3683.tistory.com

 

public static class PS
{
    public class TupleComparer : IComparer<(int x, int y)>
    {
        int IComparer<(int x, int y)>.Compare((int x, int y) t1, (int x, int y) t2)
        {
            if (t1.y == t2.y)
                return t1.x - t2.x;
            else
                return t1.y - t2.y;
        }
    }

    public static int n;
    public static (int x, int y)[] arr;

    public static void Main()
    {
        StreamWriter sw = new(new BufferedStream(Console.OpenStandardOutput()));
        string[] xy;

        n = int.Parse(Console.ReadLine());
        arr = new (int x, int y)[n];

        for (int i = 0; i < n; i++)
        {
            xy = Console.ReadLine().Split();
            arr[i] = (int.Parse(xy[0]), int.Parse(xy[1]));
        }

        Array.Sort(arr, new TupleComparer());

        foreach (var t in arr)
        {
            sw.WriteLine($"{t.x} {t.y}");
        }
        
        sw.Close();
    }
}

 

직전의 11650번 문제는 운좋게도 ValueTuple의 정렬 기준이 문제와 맞아떨어져 아무런 추가 작업 없이 정렬이 가능했지만, 이번 문제는 그렇지 않다. 정렬 기준을 새롭게 변경해야 한다.

C++을 다뤄봤던 사람이라면 알 것이다. sort를 호출할 때 자신만의 compare 함수를 콜백으로 넘겨줄 수 있다.

C# 또한 그렇게 할 수 있다. 단, 메서드가 아닌 객체를 전달한다. 그리고 그 객체는 IComparer 인터페이스를 상속받은 객체여야 한다.

 

IComparer를 상속받은 객체는 반드시 Compare 메서드를 작성해야 한다.

Compare 메서드는 반환값을 기준으로 두 변수를 비교하는데, 만약 변수 x와 y에 대하여 Compare 메서드가 음수를 반환한다면 x가 y보다 순서가 빠르다는 뜻이고, 양수를 반환한다면 그 반대이다. 0을 반환하는 것은 순서가 같다는 뜻이다.

아래는 MS의 공식 문서이다. 예시가 작성되어 있으니 꼭 읽어보길 권장한다.

 

 

IComparer<T>.Compare(T, T) 메서드 (System.Collections.Generic)

두 개체를 비교하여 한 개체가 다른 개체보다 작거나, 같거나 또는 크다는 것을 나타내는 값을 반환합니다.

learn.microsoft.com

 

이 문제는 11650번 문제와 동일한 오름차순 정렬이지만 x가 아닌 y를 우선시하고 있다.

따라서 Compare 메서드는 아래의 기준으로 작성할 수 있다.

 

1) y가 같다면 x를 기준으로 정렬하라

2) y가 다르다면 y를 기준으로 정렬하라

 

반환값은 뺄셈으로 쉽게 구할 수 있다.

'백준 > 단계별' 카테고리의 다른 글

백준 1002 C#) 터렛  (0) 2023.03.07
백준 18870 C#) 좌표 압축  (0) 2022.12.30
백준 11650 C#) 좌표 정렬하기  (0) 2022.10.12
백준 1436 C#) 영화감독 숌  (0) 2022.05.28
백준 1018 C#) 체스판 다시 칠하기  (0) 2022.05.27

댓글