이전 문제처럼 ValueTuple을 사용해서 풀어보자.
*IComparable, IComparer에 대해 모른다면 이 글을 먼저 읽어보자.
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의 공식 문서이다. 예시가 작성되어 있으니 꼭 읽어보길 권장한다.
이 문제는 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 |
댓글