[BAEKJOON] 백준 1268: 임시 반장 정하기 (C#)

2024. 5. 21. 16:11IT/BaekJoon

문제 링크

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

 

 

문제

오민식 선생님은 올해 형택초등학교 6학년 1반 담임을 맡게 되었다. 오민식 선생님은 우선 임시로 반장을 정하고 학생들이 서로 친숙해진 후에 정식으로 선거를 통해 반장을 선출하려고 한다. 그는 자기반 학생 중에서 1학년부터 5학년까지 지내오면서 한번이라도 같은 반이었던 사람이 가장 많은 학생을 임시 반장으로 정하려 한다.

그래서 오민식 선생님은 각 학생들이 1학년부터 5학년까지 몇 반에 속했었는지를 나타내는 표를 만들었다. 예를 들어 학생 수가 5명일 때의 표를 살펴보자.

위 경우에 4번 학생을 보면 3번 학생과 2학년 때 같은 반이었고, 3번 학생 및 5번 학생과 3학년 때 같은 반이었으며, 2번 학생과는 4학년 때 같은 반이었음을 알 수 있다. 그러므로 이 학급에서 4번 학생과 한번이라도 같은 반이었던 사람은 2번 학생, 3번 학생과 5번 학생으로 모두 3명이다. 이 예에서 4번 학생이 전체 학생 중에서 같은 반이었던 학생 수가 제일 많으므로 임시 반장이 된다.

각 학생들이 1학년부터 5학년까지 속했던 반이 주어질 때, 임시 반장을 정하는 프로그램을 작성하시오.

 

 

입력

첫째 줄에는 반의 학생 수를 나타내는 정수가 주어진다. 학생 수는 3 이상 1000 이하이다. 둘째 줄부터는 1번 학생부터 차례대로 각 줄마다 1학년부터 5학년까지 몇 반에 속했었는지를 나타내는 5개의 정수가 빈칸 하나를 사이에 두고 주어진다. 주어지는 정수는 모두 1 이상 9 이하의 정수이다.

 

 

출력

첫 줄에 임시 반장으로 정해진 학생의 번호를 출력한다. 단, 임시 반장이 될 수 있는 학생이 여러 명인 경우에는 그 중 가장 작은 번호만 출력한다.

 

 

 

통과한 답안

namespace _1268
{
    internal class Program
    {
        static void Main(string[] args)
        {
            int students = int.Parse(Console.ReadLine());
            int[,] stuClass = new int[students, 5];

            for (int i = 0; i < students; i++)
            {
                string[] inputs = Console.ReadLine().Split(' ');
                for (int j = 0; j < 5; j++)
                {
                    stuClass[i, j] = int.Parse(inputs[j]);
                }
            }

            int maxSameClassCnt = 0;
            int tmpPresident = 1;

            for (int i = 0; i < students; i++)
            {
                int sameClassCnt = 0;

                for (int j = 0; j < students; j++)
                {
                    if (i == j) continue;

                    for (int k = 0; k < 5; k++)
                    {
                        if (stuClass[i, k] == stuClass[j, k])
                        {
                            sameClassCnt++;
                            break;
                        }
                    }
                }

                if (sameClassCnt > maxSameClassCnt)
                {
                    maxSameClassCnt = sameClassCnt;
                    tmpPresident = i + 1;
                }
            }

            Console.WriteLine(tmpPresident);
        }
    }
}

 

문제를 해석하면 1학년부터 5학년까지 각각 학생들의 반이 주어진 경우,

각 학생들 중에서 같은 반을 많이 했던 학생을 임시 반장으로 선출하는 것으로

간단하게 아는 학생이 가장 많은 학생을 임시 반장으로 선출한다는 논리이다.

 

문제를 해결하는데 있어서는 2차원 배열 int[,]를 사용해서

각 학생의 학년별 반을 저장하고, 이를 다른 학생들과 비교해서

같은 반이 많았던 학생을 찾는 방법을 사용하였다.

for (int j = 0; j < students; j++)
{
    if (i == j) continue;

	~~
}

 

이 if문은 없어도 코드가 작동하는데는 이상이 없으나 (자기 자신은 항상 같은 반이므로)

좀 더 정확한 동작을 위해서 필요한 처리이다.

 

 

이 문제를 푸는데 있어서 틀릴 수 있게 유도한 부분이 2가지가 있는데

 

1. 1학년부터 5학년까지 지내오면서 한번이라도 같은 반이었던 사람이 가장 많은 학생

의 뜻은 a와 b가 있는 경우 같은 반이 여러 번이라도 카운트는 1을 증가시켜야 된다는 것이다.

if (stuClass[i, k] == stuClass[j, k])
{
    sameClassCnt++;
    break; // 더 이상 탐색할 필요가 없으므로
}

 

2. 임시 반장이 될 수 있는 학생이 여러 명인 경우에는 그 중 가장 작은 번호

같은 카운트를 갖고 있다면 임시 반장을 변경하지 않는다는 뜻이다.

int tmpPresident = 1; // 모두 같은 경우에는 1번 학생이 임시반장

if (sameClassCnt > maxSameClassCnt) // 같은 경우에는 임시 반장을 변경하지 않음
{
    maxSameClassCnt = sameClassCnt;
    tmpPresident = i + 1;
}

 

위의 두 부분을 코드에 반영한다면 문제를 수월하게 풀 수 있을 것이다.