HSAT/Level2

[C++]Softeer/HSAT Level2 - 전광판

hj967 2023. 8. 2. 17:15

<문제>

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

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

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

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

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

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

제약조건
하나의 입력에서 1개 이상 1000개 이하의 테스트 케이스를 해결해야 한다.A와 B는 한 자리 이상 다섯 자리 이하의 자연수이다.A와 B는 숫자 0으로 시작하지 않는다.A와 B는 서로 다르다.

 

<제출답안>

#include<iostream>
#include<string>
#include<cmath>
#include<algorithm>

using namespace std;

bool bool_of_number[10][7]
		=
		{
			{1,1,1,1,1,1,0},		//0
			{0,1,1,0,0,0,0},		//1
			{1,1,0,1,1,0,1},		//2
			{1,1,1,1,0,0,1},		//3
			{0,1,1,0,0,1,1},		//4
			{1,0,1,1,0,1,1},		//5
			{1,0,1,1,1,1,1},		//6
			{1,1,1,0,0,1,0},		//7
			{1,1,1,1,1,1,1},		//8
			{1,1,1,1,0,1,1}			//9
		};

int cmp(string a, string b)
{
	string a_element, b_element;
	int answer = 0;

	for(int j=0;j<5;j++)
	{
		if(a[j] == 'X' && b[j] == 'X')
		{
			// Do nothing
		}

		else if(a[j] == 'X')
		{
			b_element = b[j];
			for(int k=0;k<7;k++)
			{
				if(bool_of_number[stoi(b_element)][k] == 1)
					answer ++;
			}
		}

		else if(b[j] == 'X')
		{
			a_element = a[j];
			for(int k=0;k<7;k++)
			{
				if(bool_of_number[stoi(a_element)][k] == 1)
					answer ++;
			}
		}
		else
		{
			a_element = a[j];
			b_element = b[j];
			if(a[j]!=b[j])
			{
				for(int k=0;k<7;k++)
				{
					if(bool_of_number[stoi(a_element)][k] 
						== bool_of_number[stoi(b_element)][k])
						answer += 0 ;
					
					else
						answer += 1 ;
				}
			}
		}
	}
	return answer;
}


int main(int argc, char** argv)
{
	int T;			
	int answer;				

	cin>>T;				
	string given_value[T][2];


	for(int i=0;i<T;i++)
	{
		cin>>given_value[i][0];
		cin>>given_value[i][1];

		while(given_value[i][0].size()!=5)
			given_value[i][0] = "X"+given_value[i][0];
		while(given_value[i][1].size()!=5)
			given_value[i][1] = "X"+given_value[i][1];
	}

	
	for(int i=0;i<T;i++)
	{
		answer = cmp(given_value[i][0],given_value[i][1]);
		cout<<answer;
		cout<<"\n";
	}

	
	return 0;
}

상당히 길다.

쉽게 이해하자면 다음과 같다.

1. 각각의 숫자마다 스위치가 켜진 전구를 1, 꺼진 전구를 0으로 둔다. (bool_of_number 참조)

나는 왼쪽위부터 시계방향으로 한바퀴 돈 뒤 가운데를 마지막으로 셌다.

2. 0~9 까지 할당되지않은 경우 문자 'X' 를 붙여준다. (main 함수 참조)

비어있다고 0을 할당하게 되면 0과 다른 숫자 사이에 차이를 구해주므로 안된다. //내가 이런짓을 해서 시간이 좀 걸렸음

그래서 전혀 숫자와 상관없는 X를 넣어주게되었다.

 

3. 5자리 숫자를 모두 비교하는 함수를 만들어준다. (cmp 함수 참조)

같은 자리가 모두 'X'이면 아무 행위 안함

같은 자리 중 하나만 'X' 이면 아예 꺼져있다 켜지거나 켜져있다 꺼진것이므로 'X'가 아닌 숫자의 켜져있는 전구 갯수를 구한다.

같은 자리가 모두 'X'가 아니면 한자리 한자리씩 총 7자리 모두 비교해준다.

 

4. cmp 함수를 응용해서 모든 케이스마다 계산되도록 해준다. (main 함수 참조)

 

어려운 문제는 아니고 그냥 완전 탐색 정도의 개념이다. 풀이가 다소 무식하다.

나중에 더 좋은 풀이가 생각나면 올려보도록 하겠다.