모름

문제 요약

 

손익분기점을 계산하는 문제다. A에 고정 비용(임대료, 재산세, 보험료 같은 류)이 주어진다. B에 가변 비용(한 대의 제품을 판매할 때 드는 비용)이 주어진다. C는 판매가다. A, B, C가 주어졌을 때 손익분기점을 구하는 프로그램을 작성해야한다.

 

 

 


 

 

 

입력과 출력

 

입력 : 첫째 줄에 A B C 가 빈 칸을 사이에 두고 순서대로 주어진다.

출력 : 첫째 줄에 손익분기점, 즉 최초로 이익이 발생하는 판매량을 출력한다. 손익분기점이 존재하지 않으면 -1을 출력.

 

예제 입출력 보기

더보기

(1)입력: 1000 70 170

(2)출력: 11

 

 

 


 

 

 

풀이

 

우선 가변비용과 고정비용을 합한 가격에 판매 개수 N 개를 계속 곱해줍니다. 그리고 판매가 기준으로 판매 개수 N개를 곱한 값도 따로 구해줍니다. (판매가*판매개수)가 결국 (고정비용+가변비용*판매개수) 가격을 넘어설때까지 판매개수의 증가는 계속되야합니다. 그리고 최초로 가격이 넘어섰을 때의 판매개수를 출력시키면 됩니다.

 

그리고 예외처리로 손익분기점이 존재하지 않는 경우인데, 이 경우는 판매가가 가변비용보다 적은 경우일 뿐이므로 계산이 시작되기 전 판매가와 가변비용을 비교해 손익분기점 유무를 판단합니다.

 

 

 


 

 

 

코드 구현

 

...코드

static void Main(string[] args)
{
    GetABC(Console.ReadLine(), out int a, out int b, out int c); 
}
        
static void GetABC(string input, out int A, out int B, out int C)
{
    //A는 고정비용, B는 가변비용, C는 판매가
    string[] ABC = input.Split(' ');
    A = int.Parse(ABC[0]);
    B = int.Parse(ABC[1]);
    C = int.Parse(ABC[2]);
}

우선 A, B, C를 입력받는 함수를 만들고 입력받아주겠습니다.

 

static int GetBreakEvenPoint(int a, int b, int c)
{
    if (b > a)
        return -1;
             
    int costAmount  = a;
    int salesAmount = 0;

    for (int i = 1; true; i++)
    {
        costAmount += b;
        salesAmount += c;

        if (salesAmount > costAmount)
            return i;
    }
}

GetBreakEvenPoint() 함수를 구현했습니다. b>a, 즉 원가가 판매가보다 크면 영원히 손익분기점에 도달할 수 없기때문에 false를 의미하는 -1를 리턴해줍니다.

 

그리고 지출총액(costAmount)에 고정비용 a 를 우선 담아주겠습니다. 이후 for문을 활용하여 지출총액과 판매총액을 i 개수만큼 물건을 팔면서 판매총액이 지출총액보다 커질때까지 i개수만큼 반복해줄건데요. 결국 판매총액이 커지게 되면 i번째 판매개수를 리턴하면서 함수를 종료합니다.

 

static void Main(string[] args)
{
    GetABC(Console.ReadLine(), out float a, out float b, out float c);
    Console.WriteLine(GetBreakEvenPofloat(a, b, c));
}

마지막으로 앞서 작성한 함수를 호출하여 결과값을 출력하면 끝인줄 알았습니다.

 

결과는 시관초과가 발생합니다. 현재 작성된 알고리즘이 세타(n)의 복잡도를 가지는것 같은데. 앞서 문제 조건 중 이런 내용이 있었습니다. A,B,C는 자연수 21억 이하의 수라는 조건이었습니다. 이는 상황에 따라서 몇십억번을 반복문을 돌려야 할 수 도 있다는 겁니다.

 

때문에 수학을 활용하여 이 알고리즘을 풀어야겠습니다.

 

 

 


 

 

 

수학

 

A는 1000, B는 70, C는 170인 상황에서 C가 총 판매가에 도달하는 시기는 11개째 팔았을 때입니다. 10개째는 A+B = 1700, C는 1700원으로 가격이 같아지며 이후 판매가가 원가를 초과하게됩니다.

 

원가는 1개 1000+70*1, 2개 1000+70*2, 3개 1000+70*3 ... n개 1000+70*n 의 값을 가지게 됩니다. 이를 식으로 풀어쓰면 cost = a+b*n 이 되겠습니다.

판매가는 1개 170, 2개 340, 3개 510 ... n개 170*n 의 값을 가지게 됩니다.  판매가는 c*n이 되겠습니다.

 

그럼 저희가 해야할 것은 1000+70*n과 170*n이 처음으로 값이 같아지는 첫 교차점을 확인하면 되는데요. 이는 두 등차수열의 교점을 구하는 식으로 해결 가능합니다.

 

등차수열의 교점을 구하는 70*n+1000 = 170*n 란 식을 작성하면, 1000 = 100n 이며, n은 10이 됩니다. 두 등차수열의 첫 교점은 10으로 딱 맞아떨어지며, 현재 구하고있는 답은 판매가가 원가를 초과해야하므로 교점인 10에서 1을 더해준 값이 출력값이 되게됩니다.

 

이제 이 내용을 코드로 작성하면 되겠습니다.

 

//a는 고정비용, b는 가변비용, c는 판매가
//a+b*n = c*n;
//a = c*n - b*n;
//a = (c-b)n
//a/(c-b) = n

대략 주석으로 식을 풀어보면 위와같이 됩니다. n을 구할 수 있겠네요.

 

 

 


 

 

코드(2)

 

static int GetBreakEvenPoint(int a, int b, int c)
{
    int n = a / (c - b);
    return n+1;
}

앞서 작성한 코드보다 훨씬 심플한 코드가 작성되었습니다. int형이기 때문에 나머지값을 알아서 버리고 교점 최근처까지 다가갈수 있습니다. 거기서 1개만큼 더 팔면 교점을 지나쳐 c의 값이 더 커지게 됩니다.

 

 

 


 

 

 

출력 화면

 

수학공부좀 해야겠네요! ㅜㅜ

 

 

 


 

코드전문보기

 

더보기
class Program {
    static void Main(string[] args)
    {
        GetABC(Console.ReadLine(), out int a, out int b, out int c);
        Console.WriteLine(GetBreakEvenPoint(a, b, c));
    }
        
    static void GetABC(string input, out int A, out int B, out int C)
    {
        string[] ABC = input.Split(' ');
        A = int.Parse(ABC[0]);
        B = int.Parse(ABC[1]);
        C = int.Parse(ABC[2]);
    }

    static int GetBreakEvenPoint(int a, int b, int c)
    {
        if (b >= c)
            return -1;

        int n = a / (c - b);
        return n+1;
    }
}