본문 바로가기

알고리즘 문제 풀어보기

[백준 1475] 방 번호 문제

1475번 방 번호 문제


문제


다솜이는 은진이의 옆집에 새로 이사왔다. 다솜이는 자기 방 번호를 예쁜 플라스틱 숫자로 문에 붙이려고 한다.

다솜이의 옆집에서는 플라스틱 숫자를 한 세트로 판다. 한 세트에는 0번부터 9번까지 숫자가 하나씩 들어있다. 다솜이의 방 번호가 주어졌을 때, 필요한 세트의 개수의 최솟값을 출력하시오. (6은 9를 뒤집어서 이용할 수 있고, 9는 6을 뒤집어서 이용할 수 있다.)


입력


첫째 줄에 다솜이의 방 번호 N이 주어진다. N은 1,000,000보다 작거나 같은 자연수 또는 0이다.



출력


첫째 줄에 필요한 세트의 개수를 출력한다.



입력 예제


9999


출력 예제


2


이 문제는 얼마나 빨리 규칙을 찾고, 그 규칙을 어떤 방법으로 처리해 결과를 나타낼 것이냐에 따라 달린 문제이다.

규칙을 찾는 것은 그리 오래 걸리지는 않았다.


6, 9를 제외한 나머지 숫자들은 각 숫자의 개수만큼 숫자세트가 필요하고

6, 9는 (나머지 숫자 중 가장 많은 숫자의 개수 * 2 < 6, 9의 개수) 이 조건이라면

(6, 9의 개수+1) / 2 = 필요한 숫자세트 개수가 된다.


문제는 그 규칙들을 어떻게 처리할까를 고민하다 시간이 꽤 오래 걸려버렸다 ㅠㅠ

여차저차 풀었는데 다행이 정답이라 안도했지만 머릿속이 복잡하다...

너무 어렵게 생각을 했나? 아무튼 문제를 더 빠르게 풀 수 있도록 생각을 최적화할 필요가있다.


짠 코드는 이렇다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#pragma warning(disable : 4996)
 
int main()
{
    // n : 입력받을 변수, set : 셋트 수=6,9를 제외한 나머지 수 중 가장 많이 있는 수의 개수, num[i] : 0~9까지 숫자의 개수
    int set = 1;
    int num[10= { 0 };

    //SixOrNine : 6이나 9의 개수를 받을 변수
    int SixOrNine;

    // c : 입력받은 정수n을 문자열로 받을 배열
    char *= (char*)malloc(sizeof(char* 1000000);
    scanf("%s", c);
 
    int length = strlen(c);
    for (int i = 0; i < length; i++)
    {
        char numdata = c[i];
        switch (numdata)
        {
        case '0':
            num[0]++;
            break;
        case '1':
            num[1]++;
            break;
        case '2':
            num[2]++;
            break;
        case '3':
            num[3]++;
            break;
        case '4':
            num[4]++;
            break;
        case '5':
            num[5]++;
            break;
        case '6':
            num[6]++;
            break;
        case '7':
            num[7]++;
            break;
        case '8':
            num[8]++;
                break;
        case '9':
            num[9]++;
                break;
        }
    }
    for (int i = 0; i < 10; i++)
    {
        if (i != 6 && i != 9)
        {
            //6,9를 제외한 숫자 중 가장 많이 있는 수 -> set에 넣음
            if (set <= num[i])
                set = num[i];
        }
    }
    SixOrNine = num[6+ num[9];    //6, 9의 개수
 
 
    //나머지 숫자 중 가장 많은 수의 개수 >= 6, 9 숫자 개수
    //이 조건엔 set수가 숫자세트 수가 됨
    if (set >= SixOrNine)
        printf("%d\n", set);
    //set*2 한 값보다 6, 9의 개수가 더 많으면
    //(6, 9개수 + 1) / 2 한 값이 숫자세트 수가 됨
    else
    {
        if ((set * 2> SixOrNine)
            printf("%d\n", set);
        else if ((set * 2<= SixOrNine)
            printf("%d\n", (SixOrNine + 1/ 2);
    }
}
cs


뭔가 노가다 작업을 하게 되었다...(switch 문으로 각 숫자의 개수를 처리하려니...)

이렇게 처리하는 것보다 더 간단히 처리할 수 있는 방법을 알고있다면 그리 하는게 더 좋은 코드가 될 것이다.


그리고 지금 올리면서 봤는데

if (set >= SixOrNine)

printf("%d\n", set);


이 구문은 안 써도 된다. (어차피 (set * 2) > SixOrNine 조건으로만 처리하면 되는 것...)

뭔가 하나하나 차근차근 처리하자라는 생각으로 하다보니 그런 생각들이 코드에 반영되버린 것 같다.