본문 바로가기

박기완 코딩교육/정보올림피아드 대비

코드업 4432 십자카드 초등 정올

이번 십자카드 문제는  시계방향이란 컨셉에 어느 점을 시작점으로 하냐에따라  숫자가 달라지다보니 뭔가 어렵다란 느낌이 들 수 도 있다.

하지만 실제론 1차원배열에 넣고 숫자읽기만 하면 쉽게 해결되는 문제다.

단순히 십자카드가 주어지고 시계수 찾아라하면 레벨1정도로해서 간단하게 끝날 수준인데

난이도가 하나 더 올라갔다.

모든 시계수들 중에서 입력된 카드의 시계수가  몇번째로 작냐라는 조건.

그래서 모든 시계수를 어떻게 구해야할지 고민해봤다.

 

십자카드 숫자들에대해 시계수를 만들어내는 원리를 좀더 생각해봤지만

결국엔  나올 수 있는 숫자 경우수가 9*9*9*9 즉 6561개밖에 없어서 그냥 일일이 다 따져도 시간초과가 안뜰거란 생각이 들었다.

 

이렇게까지 생각후 코드구현 시작

 

#include <stdio.h>
#include <vector>

using namespace std;

//int checked
//숫자 넣으면 시계수도 리턴해주고,  이미 확인한 숫자들은 체크처리해줌좋겠다
//이런 목적의 함수 구현
int checkSigae(int num, int *number, int *check)
{
	
	int arr[4] = {num/1000, (num/100)%10, (num/10)%10, (num%10)};
	if(number[num]) return number[num];
	
	
	int min=10000;
	vector<int> vec;
		
	for(int i=0;i<4;i++){
		int sigae = arr[(i+0)%4]*1000+arr[(i+1)%4]*100+arr[(i+2)%4]*10+arr[(i+3)%4];
		if(min > sigae) min = sigae;
		vec.push_back(sigae);
		
	}
	check[min] = 1;
	for(int i=0;i<vec.size();i++){
		number[vec[i]] = min;	
	}
	
	return min;
}

int main()
{
	int arr[4]={};
	int number[10000]={};
	int check[10000]={};
	scanf("%d %d %d %d",&arr[0],&arr[1],&arr[2],&arr[3]);
	
	int sigae = checkSigae(arr[0]*1000+arr[1]*100+arr[2]*10+arr[3], number,check);
	
	
	int cnt=0;
	
	//시계수 체크 
	for(int i=1;i<=9;i++){
		for(int j=1;j<=9;j++){
			for(int k=1;k<=9;k++){
				for(int o=1;o<=9;o++){
					checkSigae(i*1000+j*100+k*10+o, number, check);
				}
			}
		}
	}
	
	for(int i=1111;i<sigae;i++){
		if(check[i]) cnt++;
	}
	
	printf("%d",cnt+1);
	

	return 0;	
}