코딩테스트/ELSE

[Softeer] 전광판 - JAVA

5월._. 2023. 5. 14.
728x90

1. 문제

 

Softeer

연습문제를 담을 Set을 선택해주세요. 취소 확인

softeer.ai

현대차그룹에 다니는 당신은 전세계 유가 변동에 대해 실시간으로 파악하기 위해 사무실에 유가를 실시간으로 표시하는 전광판을 설치하였다. 전광판은 최대 다섯 자리의 자연수만을 표시할 수 있도록, 아래와 같이 육각형 모양의 전구 7×5=35개로 구성되어 있다.

8자 모양의 전구 묶음은 0부터 9까지의 숫자를 표현할 수 있으며, 표현 방법은 아래와 같다. 아래 그림에서 전구가 켜졌으면 검정색, 꺼졌으면 옅은 회색으로 표현되었다.

예를 들어, 전광판을 통해 9881를 표현하면 아래와 같다. 만의 자리 수가 없기 때문에, 만의 자리에 해당하는 전구들이 모두 꺼져 있음에 유의하라.

예를 들어, 전광판을 통해 10724를 표현하면 아래와 같다.

각각의 전구에는 스위치가 달려 있다. 전구에 달려 있는 스위치를 누를 때, 그 전구가 켜져 있었다면 꺼지고, 그 전구가 꺼져 있었다면 켜진다.

 

지금 전광판에 자연수 A가 표시되어 있는데, 유가가 변동됨에 따라 전광판에 표시된 자연수를 B로 바꿔야 한다. 이러한 목표를 달성하기 위해 스위치를 최소 몇 번 눌러야 하는지를 구하는 프로그램을 작성하라.


2. 풀이

static 변수

모든 메서드에서 쓰는 변수를 static으로 만들었다.

boolean[][] num_switch num_switch[숫자 i][전구번호 j]가 true라면 i를 만들 때 j번 전구가 켜져야 한다는 의미다.
int[][] number number[숫자][필요한전구목록] 숫자 당 켜져야 하는 전구를 배열로 저장했다.

 

초기화

1.  위에서부터 시계방향으로 1~6까지 순서를 매긴 다음, 가운데는 7번을 붙였다.

2.  number 배열에 0부터 9까지 어떤 전구를 켜야 하는지 숫자로 저장한다.

3.  number배열에 있는 숫자만 num_switch에 true를 저장한다. 이때, number배열에 있는 숫자-1로 num_switch에 접근해야 하는데, 그 이유는 전구 번호를 1번부터 매겼으면서 num_switch배열크기를 7까지로 만들었기 때문이다. ^___^ 이 글을 보는 사람들은 둘 중 하나만 하길 바란다. 0부터 매기고 7로 만들던가 1부터 매기고 8 크기로 만들던가....

public static void init(){
    number = new int[][]{
        {1,2,3,4,5,6},
        {2,3},
        {1,2,4,5,7},
        {1,2,3,4,7},
        {2,3,6,7},
        {1,3,4,6,7},
        {1,3,4,5,6,7},
        {1,2,3,6},
        {1,2,3,4,5,6,7},
        {1,2,3,4,6,7}
    };

    num_switch = new boolean[10][7];
    for(int i=0;i<10;i++){
        for(int j=0;j<number[i].length;j++){
            num_switch[i][number[i][j]-1] = true;
        }
    }
}

 

숫자 세기

한 글자 a,b를 입력받아서 같은 자리의 전구가 같은 값인지 확인한다. 다른 전구의 값을 반환한다.

public static int count(int a, int b){
    int cnt = 0;
    for(int i=0;i<7;i++){
        if(num_switch[a][i] != num_switch[b][i]) cnt++;
    }
    return cnt;
}

 

전광판 비교

1.  코드를 간단하게 짜기 위해서 a가 b보다 작다면 둘 값을 바꾼다.

2.  숫자%10을 하면 가장 끝 자리 숫자가 나온다. change(a%10, b%10)의 반환값을 answer에 저장한 후, a와 b 모두 다음 숫자 탐색을 위해 10으로 나눈다.

3.  a,b 둘 중 하나라도 0이 된다면(b가 더 작은 수이기 때문에 b만 체크해도 된다) 탐색을 멈춘다.

4.  a의 남은 숫자들은 모두 꺼진 전구를 숫자에 맞게 켜야 한다. 초기화 때 사용했던 number배열의 length로 a의 맨 끝자리(a%10)가 몇 개의 전구를 켜야 하는지 알아낸다. 알아낸 값은 answer에 더하고, a는 다시 10으로 나눈다.

5.  4번 반복까지 마무리됐다면 answer을 반환한다.

public static int compare(int a, int b){
    if(a<b) {
        int tmp = a;
        a = b;
        b = tmp;
    }

    int answer = 0;
    while(a>0 && b>0){
        answer += change(a%10,b%10);
        a/=10;
        b/=10;
    }

    while(a>0){
        answer += number[a%10].length;
        a/=10;
    }

    return answer;
}

 

메인

1.  init()메서드로 number, num_switch배열을 초기화한다.

2.  T를 입력받은 뒤, 그 수만큼 반복하면서 a, b를 입력받는다. 

3.  compare(a,b)값을 StringBuilder sb에 더한다.

4.  sb를 출력한다.

public static void main(String args[]) throws Exception
{
    init();
    BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
    int T = Integer.parseInt(in.readLine());
    StringBuilder sb = new StringBuilder();
    StringTokenizer st;
    int a, b;
    for(int tc=0;tc<T;tc++){
        st = new StringTokenizer(in.readLine());
        a = Integer.parseInt(st.nextToken());
        b = Integer.parseInt(st.nextToken());
        sb.append(compare(a,b)).append('\n');
    }
    System.out.print(sb);
}

 

전체 코드

import java.util.*;
import java.io.*;


public class Main
{
    static boolean[][] num_switch;
    static int[][] number;
    public static void main(String args[]) throws Exception
    {
        init();
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        int T = Integer.parseInt(in.readLine());
        StringBuilder sb = new StringBuilder();
        StringTokenizer st;
        int a, b;
        for(int tc=0;tc<T;tc++){
            st = new StringTokenizer(in.readLine());
            a = Integer.parseInt(st.nextToken());
            b = Integer.parseInt(st.nextToken());
            sb.append(compare(a,b)).append('\n');
        }
        System.out.print(sb);
    }

    public static void init(){
        number = new int[][]{
            {1,2,3,4,5,6},
            {2,3},
            {1,2,4,5,7},
            {1,2,3,4,7},
            {2,3,6,7},
            {1,3,4,6,7},
            {1,3,4,5,6,7},
            {1,2,3,6},
            {1,2,3,4,5,6,7},
            {1,2,3,4,6,7}
        };

        num_switch = new boolean[10][7];
        for(int i=0;i<10;i++){
            for(int j=0;j<number[i].length;j++){
                num_switch[i][number[i][j]-1] = true;
            }
        }
    }

    public static int count(int a, int b){
        int cnt = 0;
        for(int i=0;i<7;i++){
            if(num_switch[a][i] != num_switch[b][i]) cnt++;
        }
        return cnt;
    }

    public static int compare(int a, int b){
        if(a<b) {
            int tmp = a;
            a = b;
            b = tmp;
        }

        int answer = 0;
        while(a>0 && b>0){
            answer += change(a%10,b%10);
            a/=10;
            b/=10;
        }

        while(a>0){
            answer += number[a%10].length;
            a/=10;
        }

        return answer;
    }
}

3. 결과

난 이런 문제를 풀 때마다 정말 파이썬으로 돌아가고싶다 ^_______^......

댓글