[BAEKJOON] 백준 2546: 경제학과 정원영 (C#)

2024. 6. 7. 16:26IT/BaekJoon

문제 링크

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

 

 

문제

C언어 성적이 나쁜 학생이 C언어를 드랍하고 경제학 원론을 듣는다면, 그 학생은 두 과목 수강생의 평균 IQ를 올려준다.

이 말은 어떤 학생이 직접 C언어를 드랍하고 경제학 원론을 수강하면서 증명하였다.

각 학생의 IQ가 주어진다. 이때, C언어 수강생 중에 C언어를 드랍하고 경제학 원론을 수강해서 두 과목의 평균 IQ를 모두 올려줄 수 있는 사람의 수를 구하시오.

 

 

입력

첫째 줄에 테스트 케이스의 개수 T가 주어진다. 각 테스트 케이스는 빈 줄로 구분되며, 다음과 같이 구성되어 있다. 

테스트 케이스의 첫째 줄에는 C언어 수강생의 수 N과 경제학 원론 수강생의 수 M이 주어진다. 둘째 줄에는 N+M 개의 숫자가 공백으로 구분되어 주어진다. 

처음 N개의 숫자는 C언어 수강생의 IQ이며, 다음 M개의 숫자는 경제학 원론 수강생의 IQ이다.

N과 M은 200,000보다 작거나 같은 자연수이고, N은 2보다 크거나 같다. IQ는 100,000보다 작거나 같은 자연수이다.

 

 

출력

각 테스트 케이스의 정답을 한 줄에 하나씩 차례대로 출력한다.

 

 

 

통과한 답안

namespace _2546
{
    internal class Program
    {
        static void Main(string[] args)
        {
            int T = int.Parse(Console.ReadLine());

            for (int i = 0; i < T; i++)
            {
                Console.ReadLine();

                string[] inputs = Console.ReadLine().Split(' ');
                int N = int.Parse(inputs[0]);
                int M = int.Parse(inputs[1]);
                int[] CIQ = Console.ReadLine().Split(' ').Select(int.Parse).ToArray();
                int[] ecoIQ = Console.ReadLine().Split(' ').Select(int.Parse).ToArray();

                long CIQSum = CIQ.Select(x => (long)x).Sum();
                long ecoIQSum = ecoIQ.Select(x => (long)x).Sum();

                double CIQAver = (double)CIQSum / N;
                double ecoIQAver = (double)ecoIQSum / M;

                int cnt = 0;

                for (int j = 0; j < N; j++)
                {
                    double newCIQAver = (double)(CIQSum - CIQ[j]) / (N - 1);
                    double newEcoIQAver = (double)(ecoIQSum + CIQ[j]) / (M + 1);

                    if (newCIQAver > CIQAver && newEcoIQAver > ecoIQAver)
                    {
                        cnt++;
                    }
                }

                Console.WriteLine(cnt);
            }
        }
    }
}

 

문제의 설명이 조금 모호한 부분이 있어서 다시 정리하면,

첫째 줄에 테스트 케이스의 개수 T가 주어진다.

각 테스트마다 빈 줄로 구분된다.

테스트 케이스의 첫 줄에는 C언어 수강생의 수 N과 경제학 원론 수강생의 수 M이 주어진다.

둘째 줄에는 N개의 숫자로 C언어 수강생들의 IQ가 주어지고

셋째 줄에 M개의 숫자로 경제학 원론 수강생들의 IQ가 주어진다.

라는 조건으로 주어지는 문제로

 

C언어 수강생 중 1명이 C언어를 포기하고 경제학 원론을 듣는다면

C언어 수강생들의 평균 IQ와 경제학 원론 수강생들의 평균 IQ가 둘다 오르는 경우의 수를 찾는 문제이다.

 

즉, C언어를 듣는 학생을 기준으로 코드를 작성하며,

그 학생은 지금 경제학 원론을 듣고 있지 않는게 포인트이다.

 

따라서 문제를 해결하는 방법으로는

각각의 현재 평균 IQ를 구하고,

 

C언어를 듣는 학생들에 대해서 해당 학생이 빠진 경우의

새로운 평균 IQ들을 구하고, 이 새 평균 IQ가 둘 다 증가하는 경우

카운트를 증가시키면 된다.

 

이 과정에서 overflow가 발생할 수 있는 부분이

각 강의의 학생들의 IQ의 합을 구하는 부분에서 int의 범위를 벗어날 수 있으므로,

배열을 선언하는 과정에서 int가 아니라 long으로 선언하여 코드를 진행하였다.