C# 코딩테스트 강좌, 다각형의 면적 구하기

코딩 테스트에서 다각형의 면적을 구하는 문제는 알고리즘과 기하학에 대한 깊은 이해를 요구합니다. 이 글에서는 다각형의 면적을 계산하는 문제를 제시하고, 이를 해결하기 위한 접근 방법, 알고리즘, 코드 설명을 상세히 다룰 것입니다.

문제 설명

문제: 정다각형의 꼭짓점 좌표가 주어졌을 때, 이 다각형의 면적을 구하는 프로그램을 작성하시오. 각 꼭짓점은 시계방향 또는 반시계방향으로 연결된 순으로 주어진다. 좌표는 2차원 평면에서 표현된다.

입력: 첫째 줄에 정점의 개수 n (3 ≤ n ≤ 1000)이 주어진다. 그 다음 n개의 줄에 각 정점의 x, y 좌표가 주어진다.

출력: 마지막 줄에 소수점 아래 두 자리까지 반올림한 면적을 출력한다.

문제 풀이 접근 방법

다각형의 면적을 구하는 알고리즘 중 하나는
쇼벨(Shoelace) 공식을 이용하는 방법입니다. 이 방법은 다각형의 꼭짓점 좌표가 주어졌을 때, 해당 면적을 효율적으로 계산할 수 있습니다. 이 방법은 시계방향 또는 반시계방향으로 연결된 다각형의 꼭짓점에서 면적을 구하는 공식을 기반으로 합니다.

면적 계산 공식은 다음과 같습니다:

        Area = 0.5 * | Σ (xi * yi+1 - yi * xi+1) |
    

여기서 i는 0부터 n-1까지의 정수이며, (xn, yn)는 (x0, y0)로 연결됩니다. 이 공식을 통해 다각형의 면적을 쉽게 계산할 수 있습니다.

C# 구현 단계

이제 주어진 알고리즘을 C#으로 구현해보겠습니다. 구현 단계는 다음과 같습니다:

1. 입력 처리

가장 먼저, 사용자로부터 다각형의 꼭짓점 개수와 각 꼭짓점의 좌표를 입력받습니다.

2. 면적 계산

쇼벨 공식을 이용하여 입력된 좌표로 면적을 계산합니다.

3. 결과 출력

계산된 면적을 소수점 아래 두 자리까지 반올림하여 출력합니다.

코드 구현

        
        using System;

        class Program
        {
            static void Main(string[] args)
            {
                int n = int.Parse(Console.ReadLine());
                double[,] points = new double[n, 2];

                // 좌표 입력 받기
                for (int i = 0; i < n; i++)
                {
                    string[] input = Console.ReadLine().Split();
                    points[i, 0] = double.Parse(input[0]);
                    points[i, 1] = double.Parse(input[1]);
                }

                double area = CalculatePolygonArea(points, n);
                Console.WriteLine("{0:F2}", Math.Abs(area));
            }

            static double CalculatePolygonArea(double[,] points, int n)
            {
                double area = 0;

                for (int i = 0; i < n; i++)
                {
                    int next = (i + 1) % n;  // 다음 점의 인덱스
                    area += points[i, 0] * points[next, 1];
                    area -= points[next, 0] * points[i, 1];
                }

                return area * 0.5;  // 면적
            }
        }
        
    

코드 설명

포인트 정의: 입력받은 좌표를 저장하기 위해 2D 배열 points를 선언합니다.
좌표 입력: for 루프를 통해 사용자로부터 x, y 값을 입력받습니다.
면적 계산: CalculatePolygonArea 메서드에서 쇼벨 공식을 통해 면적을 계산합니다. 각 꼭짓점의 좌표를 사용하여 면적을 구하고, 마지막으로 0.5를 곱하여 최종 면적을 반환합니다.
출력: 면적을 소수점 아래 두 자리까지 출력합니다. Math.Abs() 함수를 사용하여 면적이 부정적인 경우에도 항상 양의 면적을 출력합니다.

예제

입력 예시:
4
0 0
4 0
4 3
0 3
출력 예시:
12.00

위의 예시에서는 사각형의 면적을 계산하는 것으로 0,0에서 시작하여 4,0으로 가고, 4,3으로 이어지며, 마지막으로 0,3으로 돌아오는 정사각형을 형성합니다. 해당 사각형의 면적은 4*3=12가 됩니다.

마무리

이번 글에서는 C#을 사용하여 다각형의 면적을 계산하는 방법을 배워보았습니다. 다각형 면적 계산 문제는 다양한 코딩 테스트에서 자주 출제되는 문제이며, 알고리즘적 사고를 기를 수 있는 좋은 기회입니다. 알고리즘 문제를 풀 때는 항상 다양한 접근 방식을 생각해보는 것이 중요합니다. 다음 시간에는 다른 알고리즘 문제를 통해 더 많은 경험을 쌓아가길 바랍니다.

C# 코딩테스트 강좌, 카드 게임

안녕하세요! 이번 포스팅에서는 C#을 이용한 알고리즘 코딩 테스트 문제 중 하나인 카드 게임 문제를 다루어 보겠습니다. 알고리즘 문제를 해결하는 과정에서 필요한 개념들 및 접근 방식을 상세하게 설명하도록 하겠습니다.

문제 설명

당신은 두 플레이어(A와 B)가 진행하는 카드 게임을 설계하고 있습니다. 카드 덱은 1부터 N까지의 숫자가 적힌 카드들로 이루어져 있습니다. 각 플레이어는 고유한 카드 세트를 가지고 있으며, 각 세트는 모두 고유한 카드로 구성되어 있습니다. 게임의 규칙은 다음과 같습니다:

  • 두 플레이어는 각자의 카드 중에서 하나를 선택합니다.
  • 두 카드의 숫자를 비교하여 큰 카드의 소유자가 승리합니다.
  • 동점일 경우, 플레이어 A가 승리합니다.

플레이어 A와 B의 카드 리스트가 주어질 때, 각 라운드의 승자를 결정하고 최종적으로 승자가 누구인지 출력하는 프로그램을 작성하세요.

입력 형식

입력은 다음과 같습니다:

  • 첫 번째 줄에는 카드의 개수 N (N은 1 ≤ N ≤ 1000)이 주어집니다.
  • 두 번째 줄에는 플레이어 A의 카드 리스트가 공백으로 구분되어 주어집니다.
  • 세 번째 줄에는 플레이어 B의 카드 리스트가 공백으로 구분되어 주어집니다.

출력 형식

각 라운드의 승자를 출력한 후, 최종 승자가 누구인지 출력합니다. 예를 들어:

    "A" (A의 카드, B의 카드)
    "B" (A의 카드, B의 카드)
    "A" (A의 카드, B의 카드)
    => 최종 승자: A
    

예제 입력

5
2 3 5 1 4
6 4 2 5 3
    

예제 출력

B (2, 6)
A (3, 4)
A (5, 2)
A (1, 5)
B (4, 3)
=> 최종 승자: A
    

문제 분석 및 접근 방법

이 문제를 해결하기 위해 우리는 반복문을 사용하여 각 라운드에서 카드의 숫자를 비교해야 합니다. 그 원리는 간단합니다:

  1. 입력으로 받은 플레이어 A와 B의 카드 리스트를 순서대로 비교합니다.
  2. 각 카드 쌍(플레이어 A의 카드, 플레이어 B의 카드)을 비교하여 승자를 결정합니다.
  3. 승자를 출력하고, 카운트를 통해 최종 승자를 결정합니다.

C# 코드 구현


using System;
using System.Linq;

class CardGame
{
    static void Main()
    {
        // 카드 수 입력
        int N = int.Parse(Console.ReadLine());
        
        // 플레이어 A의 카드 입력
        int[] playerA = Console.ReadLine().Split(' ').Select(int.Parse).ToArray();
        
        // 플레이어 B의 카드 입력
        int[] playerB = Console.ReadLine().Split(' ').Select(int.Parse).ToArray();
        
        // 플레이어 승리 카운트
        int scoreA = 0, scoreB = 0;

        // 각 라운드 진행
        for (int i = 0; i < N; i++)
        {
            // 각 플레이어의 카드
            int cardA = playerA[i];
            int cardB = playerB[i];

            // 승자 결정
            if (cardA > cardB)
            {
                Console.WriteLine($"A ({cardA}, {cardB})");
                scoreA++;
            }
            else if (cardB > cardA)
            {
                Console.WriteLine($"B ({cardA}, {cardB})");
                scoreB++;
            }
            else
            {
                Console.WriteLine($"A ({cardA}, {cardB})");
                scoreA++; // 동점일 경우 A 승
            }
        }

        // 최종 승자 결정
        Console.WriteLine($"=> 최종 승자: {(scoreA >= scoreB ? "A" : "B")}");
    }
}

문제 해결 과정

이제 문제 해결 과정을 단계별로 살펴보겠습니다.

1단계: 입력 읽기

우선, 사용자의 입력을 통해 카드의 개수와 플레이어 A, B의 카드 리스트를 읽었습니다. C#에서는 Console.ReadLine() 메서드를 사용하여 문자열로 입력을 받습니다. 입력 받은 문자열을 Split() 메서드를 사용하여 공백으로 분리하고, int.Parse() 메서드를 활용해 정수 배열로 변환했습니다.

2단계: 카드 비교 및 승자 결정

각 라운드를 반복문을 통해 처리했습니다. 플레이어 A와 B의 카드를 비교하고, 승자를 결정하여 출력했습니다. 승자 결정에서는 간단한 조건문을 통해 카드를 비교했습니다.

3단계: 최종 승자 출력

각 라운드 종료 후 승리 카운트를 업데이트하고, 모든 라운드가 끝난 후 최종 승자를 출력했습니다. 이 과정에서도 조건문을 사용하여 최종 점수를 비교했습니다.

복잡도 분석

이 문제의 시간 복잡도는 O(N)으로, N은 카드의 개수입니다. 입력으로 주어진 카드 리스트를 한 번씩만 확인하기 때문입니다. 공간 복잡도 또한 O(N)으로, 카드 리스트를 저장하기 위해 사용할 메모리 양이 카드의 개수 N에 비례하기 때문입니다.

추가적인 팁

이번 문제를 해결하면서 기본적인 알고리즘 사고를 발전시키는 것이 중요합니다. 다음과 같은 팁을 통해 알고리즘 문제 해결 능력을 키울 수 있습니다:

  • 문제의 조건을 명확히 이해하고, 예제를 통해 다양한 경우를 시뮬레이션 해보세요.
  • 코드를 작성하기 전에 알고리즘의 흐름을 주석으로 남기는 습관을 기르세요.
  • 풀이한 문제들을 다양한 방법으로 해결해보려는 노력을 해보세요. 같은 문제라도 다른 풀이가 있을 수 있습니다.

마치며

C#을 활용한 알고리즘 문제를 해결하는 것은 다양한 사고력과 문제 해결 능력을 기르는 데 큰 도움이 됩니다. 이번 포스팅에서 다룬 카드 게임 문제를 통해 다음 단계로 나아갈 수 있는 기회가 되길 바랍니다. 더 많은 알고리즘 문제와 해결책을 공유할 예정이니, 많은 관심 부탁드립니다!

C# 코딩테스트 강좌, 카드 정렬하기

이 글에서는 C#을 사용하여 카드 정렬하기 알고리즘 문제를 해결하는 방법을 자세히 설명합니다. 문제의 정의부터 시작하여 접근 방법, 코드 구현, 그리고 최적화 방법까지 단계별로 설명하겠습니다. 이를 통해 코딩 테스트에 필요한 알고리즘적 사고와 C# 프로그래밍 능력을 동시에 향상시킬 수 있습니다.

문제 정의

문제의 정의는 다음과 같습니다.

주어진 N개의 카드가 있습니다. 각 카드는 1부터 N까지의 유일한 정수로 표시되어 있습니다. 이러한 카드를 오름차순으로 정렬하는 알고리즘을 구현하라는 것입니다. 하지만 고정된 정렬 알고리즘 대신, 카드를 정렬하는 과정 중에 최적의 방법을 찾아보아야 합니다.

문제 해결 과정

1단계: 문제 분석

문제를 해결하는 첫 번째 단계는 문제를 면밀히 분석하는 것입니다. 카드의 개수 N이 주어지면, 데이터를 어떻게 정렬할 것인가를 생각해야 합니다. 카드의 개수가 적을 경우 간단히 직접적인 방법(버블 정렬, 선택 정렬 등)을 사용할 수 있지만, 카드의 숫자가 커질 경우 보다 효율적인 알고리즘을 선택해야 합니다.

2단계: 알고리즘 선택

효율적인 정렬 알고리즘으로는 빠른 정렬(Rapid Sort)이나 병합 정렬(Merge Sort)을 고려해 볼 수 있습니다. 이러한 정렬 알고리즘은 평균적으로 O(N log N)의 시간 복잡도를 가지기 때문에 카드가 많은 경우에도 빠르게 처리할 수 있습니다.

3단계: 구현

이제 C#으로 정렬 알고리즘을 구현해 보겠습니다. 다음은 Merge Sort를 구현한 예시 코드입니다.

using System;
using System.Linq;

class Program
{
    static void Main(string[] args)
    {
        int[] cards = { 5, 3, 8, 1, 2, 7 };

        Console.WriteLine("정렬 전 카드: " + string.Join(", ", cards));
        cards = MergeSort(cards);
        Console.WriteLine("정렬 후 카드: " + string.Join(", ", cards));
    }

    static int[] MergeSort(int[] array)
    {
        if (array.Length <= 1)
            return array;

        int midPoint = array.Length / 2;
        int[] left = MergeSort(array.Take(midPoint).ToArray());
        int[] right = MergeSort(array.Skip(midPoint).ToArray());

        return Merge(left, right);
    }

    static int[] Merge(int[] left, int[] right)
    {
        int[] result = new int[left.Length + right.Length];
        int leftIndex = 0, rightIndex = 0, resultIndex = 0;

        while (leftIndex < left.Length && rightIndex < right.Length)
        {
            if (left[leftIndex] <= right[rightIndex])
            {
                result[resultIndex++] = left[leftIndex++];
            }
            else
            {
                result[resultIndex++] = right[rightIndex++];
            }
        }

        while (leftIndex < left.Length)
        {
            result[resultIndex++] = left[leftIndex++];
        }

        while (rightIndex < right.Length)
        {
            result[resultIndex++] = right[rightIndex++];
        }

        return result;
    }
}

위 코드는 Merge Sort를 이용해 카드를 정렬하는 함수를 구현한 것입니다. 카드가 정렬되기 전과 후의 상태를 출력하도록 구성되어 있습니다.

4단계: 테스트

코드를 작성한 후, 다양한 테스트 케이스를 통해 알고리즘의 정확성과 성능을 점검해야 합니다. 예를 들어, 카드의 개수가 1인 경우, 카드의 개수가 같은 숫자로 이루어진 경우, 반대로 정렬된 카드의 경우 등 다양한 시나리오를 생각해 볼 수 있습니다.

static void TestSort()
{
    int[] testCards1 = { 4, 3, 2, 1 };
    int[] sortedCards1 = MergeSort(testCards1);
    Console.WriteLine("정렬 후 카드 1: " + string.Join(", ", sortedCards1));  // 1, 2, 3, 4

    int[] testCards2 = { 1, 1, 1, 1 };
    int[] sortedCards2 = MergeSort(testCards2);
    Console.WriteLine("정렬 후 카드 2: " + string.Join(", ", sortedCards2));  // 1, 1, 1, 1

    int[] testCards3 = { 3, 5, 2, 8, 7 };
    int[] sortedCards3 = MergeSort(testCards3);
    Console.WriteLine("정렬 후 카드 3: " + string.Join(", ", sortedCards3));  // 2, 3, 5, 7, 8
}

이러한 과정을 통해 주어진 카드들이 올바르게 정렬되는지 확인할 수 있습니다.

5단계: 최적화 및 개선

모든 구현이 끝났다면 코드의 성능을 최적화할 필요가 있습니다. C#에서는 LINQ를 사용하면 코드를 더 간결하게 쓸 수 있지만, 성능상의 문제를 고려하여 직접 구현하는 경우가 많습니다. 또한 다차원 배열이나 다른 자료구조를 활용하면 불필요한 자원 소모를 줄일 수 있습니다.

결론

이번 글에서는 카드 정렬하기 문제를 C#으로 해결하는 방법을 단계별로 설명했습니다. 알고리즘 분석, 선택, 구현, 테스트 및 최적화까지의 전 과정을 살펴보았습니다. 이러한 문제를 해결하면서 코딩 테스트에서 원하는 성과를 얻기를 바랍니다. 연습 문제를 풀고 다양한 알고리즘을 실습하며 능력을 키워보세요!

C# 코딩테스트 강좌, 구간 합

안녕하세요, 여러분! 오늘은 C#을 이용한 코딩 테스트의 중요한 주제 중 하나인 ‘구간 합’에 대해 다뤄보겠습니다. 구간 합 문제는 배열의 특정 구간에 대한 합을 효율적으로 구하는 문제입니다. 이 문제는 많은 알고리즘 문제 및 실무에서도 자주 나오는 매우 유용한 주제입니다.

문제 정의

문제를 시작하기에 앞서, 구간 합이 무엇인지 간단히 설명드리겠습니다. 구간 합이란 주어진 배열의 특정 구간(예: 배열[i] 부터 배열[j]까지)의 합을 구하는 것을 의미합니다. 이러한 문제는 다양한 방식으로 출제될 수 있습니다.

문제 예시

다음과 같은 배열이 있다고 가정해 보겠습니다.

int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

이제 우리는 주어진 배열의 구간 합을 요청하는 문제를 풀어 보겠습니다. 예를 들어, i와 j가 각각 2와 5라면, 우리는 arr[2]부터 arr[5]까지의 합, 즉 3 + 4 + 5 + 6 = 18을 구해야 합니다.

문제 해결 접근법

구간 합을 구하기 위한 첫 번째 방법은 단순 반복문을 사용하는 것입니다. 배열의 요소를 순회하여 i와 j의 값에 해당하는 구간의 합을 계산할 수 있습니다. 하지만 시간 복잡도가 O(N)으로 비효율적이라는 단점이 있습니다. 그렇다면 어떻게 하면 더 효율적으로 구간 합을 계산할 수 있을까요?

전처리 방식

구간 합 문제를 효율적으로 해결하기 위해, ‘누적 합 배열’이라는 개념을 사용합니다. 누적 합 배열은 각 인덱스까지의 합을 저장하는 배열로, 구간 합을 쉽게 계산할 수 있게 해줍니다. 누적 합 배열을 이용하면 구간 합을 O(1)의 시간 복잡도로 구할 수 있습니다.

누적 합 배열 예시

누적 합 배열을 만드는 방법을 살펴보겠습니다.


    int[] prefixSum = new int[arr.Length + 1];
    for (int i = 0; i < arr.Length; i++)
    {
        prefixSum[i + 1] = prefixSum[i] + arr[i];
    }
    

위 코드에서는 prefixSum 배열의 i+1 번째 인덱스에 arr 배열의 i번째 인덱스까지의 합을 저장합니다. 이제 특정 구간 [i, j]의 합은 prefixSum[j + 1] – prefixSum[i]로 쉽게 구할 수 있습니다.

구현

이제 누적 합 배열을 이용한 구간 합 알고리즘을 C#으로 구현해 보겠습니다.


    using System;

    public class Program
    {
        public static void Main()
        {
            int[] arr = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
            int[][] queries = { new int[] { 2, 5 }, new int[] { 0, 9 }, new int[] { 4, 7 } };

            int[] result = RangeSum(arr, queries);
            foreach (var sum in result)
            {
                Console.WriteLine(sum);
            }
        }

        public static int[] RangeSum(int[] arr, int[][] queries)
        {
            int[] prefixSum = new int[arr.Length + 1];
            for (int i = 0; i < arr.Length; i++)
            {
                prefixSum[i + 1] = prefixSum[i] + arr[i];
            }

            int[] results = new int[queries.Length];
            for (int i = 0; i < queries.Length; i++)
            {
                int l = queries[i][0];
                int r = queries[i][1];
                results[i] = prefixSum[r + 1] - prefixSum[l];
            }

            return results;
        }
    }
    

위 코드를 실행하면 각각의 쿼리에 대해 구간 합을 계산할 수 있습니다. 주의할 점은 인덱스의 범위를 항상 유효하게 유지해야 한다는 것입니다.

시간 복잡도 분석

위에서 설명한 알고리즘의 시간 복잡도는 다음과 같습니다.

  • 누적 합 배열 생성: O(N)
  • 쿼리 처리: O(1) (각 쿼리에 대해 상태 정보 접근)

결과적으로 이 알고리즘은 O(N + Q)의 시간 복잡도를 가지며, 여기서 Q는 쿼리의 개수입니다. 이처럼 구간 합 문제는 누적 합 배열을 통해 매우 효율적으로 해결할 수 있습니다.

실전 연습

이제 여러분이 구간 합 문제를 얼마나 잘 이해하고 있는지 테스트해 보세요. 아래와 같은 문제를 스스로 만들어 풀어보기를 권장합니다.

문제: 특정 구간에서의 최대값 구하기

주어진 배열의 특정 범위 내에서 최대값을 구하는 문제를 풀어보세요. 해당 문제를 누적 합을 활용해서 해결해보세요.

결론

구간 합 문제는 배열의 구간 내 합을 구하는 기본적인 알고리즘 문제입니다. 배열을 효율적으로 다루기 위해 누적 합 배열을 사용하는 방법을 배웠습니다. 이와 같은 기법은 더 복잡한 문제에서도 유용하게 활용될 수 있으므로 충분히 연습하시기 바랍니다.

이 글이 여러분의 C# 코딩 테스트 준비에 도움이 되었기를 바랍니다. 더 많은 알고리즘 문제를 풀어보며 실력을 키워보세요!

C# 코딩테스트 강좌, 트리의 지름 구하기

안녕하세요, 여러분! 오늘은 C#을 활용하여 트리의 지름을 구하는 문제를 다뤄보도록 하겠습니다. 본 글에서는 문제 정의, 알고리즘 설계, 구현과 테스트 과정을 통해 이해를 돕겠습니다.

문제 정의

트리의 지름은 트리의 두 노드 사이에 있는 가장 긴 경로의 길이를 의미합니다. 주어진 트리의 정점의 개수 nn-1개의 엣지를 통해 트리가 표현됩니다.
이를 바탕으로, 트리의 지름을 구하는 함수를 작성하세요.

입력

  • n : 정점의 수 (2 ≤ n ≤ 10^5)
  • 트리를 구성하는 n-1 개의 엣지. 각 엣지는 u v w 형태로 주어지며, uv는 연결된 정점, w는 두 정점 간의 가중치입니다.

출력

트리의 지름을 나타내는 정수 값.

알고리즘 설계

트리의 지름을 구하는 가장 일반적인 방법은 “두 번의 깊이 우선 탐색(DFS)”을 사용하는 것입니다.
아래에 간단한 절차를 정리하겠습니다.

  1. 임의의 정점에서 DFS를 실행하여 가장 먼 정점 A를 찾습니다.
  2. 정점 A에서 다시 DFS를 실행하여 가장 먼 정점 B를 찾고, 그 거리를 계산합니다.

이 방법을 통해 트리의 지름을 효율적으로 구할 수 있습니다. 최악의 경우 시간 복잡도는 O(n)입니다.

C# 코드 구현

다음은 위의 알고리즘을 기반으로 한 C# 코드입니다:

using System;
using System.Collections.Generic;

class TreeDiameter
{
    static List>[] graph;
    static bool[] visited;
    static int maxDistance;
    static int furthestNode;

    public static void Main()
    {
        int n = int.Parse(Console.ReadLine());
        graph = new List>[n + 1];

        for (int i = 1; i <= n; i++)
        {
            graph[i] = new List>();
        }

        for (int i = 0; i < n - 1; i++)
        {
            var edge = Console.ReadLine().Split();
            int u = int.Parse(edge[0]);
            int v = int.Parse(edge[1]);
            int w = int.Parse(edge[2]);
            graph[u].Add(new Tuple(v, w));
            graph[v].Add(new Tuple(u, w));
        }

        // 첫 번째 DFS로 가장 먼 정점 찾기
        visited = new bool[n + 1];
        maxDistance = 0;
        DFS(1, 0);

        // 두 번째 DFS로 지름 구하기
        visited = new bool[n + 1];
        maxDistance = 0;
        DFS(furthestNode, 0);
        
        // 결과 출력
        Console.WriteLine(maxDistance);
    }

    static void DFS(int node, int distance)
    {
        visited[node] = true;

        if (distance > maxDistance)
        {
            maxDistance = distance;
            furthestNode = node;
        }

        foreach (var neighbor in graph[node])
        {
            if (!visited[neighbor.Item1])
            {
                DFS(neighbor.Item1, distance + neighbor.Item2);
            }
        }
    }
}

코드 설명

1. graph: 인접 리스트 형식으로 트리의 엣지를 저장하기 위한 배열입니다.
2. visited: DFS 진행 중 방문한 정점을 추적하기 위한 배열입니다.
3. maxDistance: 현재까지 발견한 가장 긴 경로의 길이를 저장합니다.
4. furthestNode: 가장 먼 정점의 ID를 저장합니다.
5. Main(): 트리 구조를 입력받고, 두 번의 DFS를 호출하여 트리의 지름을 계산합니다.
6. DFS(int node, int distance): 깊이 우선 탐색 함수를 구현하여 재귀적으로 각 정점을 탐색하며 거리를 업데이트합니다.

테스트 케이스

작성한 코드를 다음과 같은 테스트 케이스로 검증할 수 있습니다:

테스트 입력

5
1 2 3
1 3 2
3 4 4
3 5 1

예상 출력

9

설명

위의 입력으로부터 트리를 그려보면 다음과 같습니다:

          1
         / \
        2   3
           / \
          4   5

트리의 지름은 노드 2에서 시작하여 노드 4까지 가는 경로로, 총 길이는 3 + 2 + 4 = 9입니다.

마치며

오늘은 C#을 활용하여 트리의 지름을 구하는 문제를 풀어보았습니다.
이 알고리즘은 트리 문제에서 매우 자주 출제되는 유형이므로, 충분히 연습하시기를 권장합니다.
여러 가지 테스트 케이스를 시도해보며 이해를 깊이 해보세요.
감사합니다!