코딩테스트/SWEA

SWEA 1225 : 암호생성기

Mev01 2021. 2. 4. 23:16

접근방법


기본적인 접근방법

큐를 사용한다.

 

추가적인 접근방법

규칙을 찾는다.

기본적인 접근방식도 있지만 이 문제의 규칙을 찾아서 연산 횟수를 줄이는 방식을 쓴다.

모든 감소시키는 수는 1, 2, 3, 4, 5를 반복하게 된다. 그리고 암호는 8개의 숫자로 이루어져 있다.

 

첫 번째 수 두 번째 수 세 번째 수 네 번째 수 다섯 번째 수 여섯 번째 수 일곱 번째 수 여덟 번째 수
-1 -2 -3 -4 -5 -1 -2 -3
-4 -5 -1 -2 -3 -4 -5 -1
-2 -3 -4 -5 -1 -2 -3 -4
-5 -1 -2 -3 -4 -5 -1 -2
-3 -4 -5 -1 -2 -3 -4 -5
-1 -2 -3 -4 -5 ...    

이해를 돕기 위해서 수를 맨 뒤로 보내지 않고 감소시키는 수를 계속 적어보았다.

표를 보면 마지막 줄이 두 번째 줄과 같은 수를 빼고 있다는 것을 볼 수 있다.

결국 이 암호생성기는 8사이클마다 같은 수를 빼고 있는 것이다.

이를 이용하면 8사이클 동안 한 수에서 총 15를 빼고 있다는 것을 알 수 있다.

 

각 수들에서 얼마를 빼야 하는지 알기 위해서 수들의 최솟값을 구한 후 그것보다 작은 15의 배수를 구한다.

(32, 35, 40, 38) -> 30이 최솟값보다 작은 15의 배수 중 제일 큰수

 

그다음 모든 수에 15의 배수를 빼준다.

(32, 35, 40, 38) -> (2, 5, 10, 8)

 

여기에서 주의할 점은 최솟값이 15의 배수가 나오는 상황이다.

최솟값이 30일 때 전체 원소마다 30을 빼주게 되면 사이클을 다 돌린 후의 원소의 값들이 나오게 된다.

이때의 값과 사이클을 하나씩 돌리면서 0 이하의 값이 만들어졌을 때 멈춘 원소들이 값이 같지 않다.

그래서 15의 배수에서 15를 뺀 값을 각각의  원소들에서 빼주어야 한다. 최솟값이 30일 경우에는 각 수에 15를 빼주게 된다.

(30, 35, 40, 38) -> (0, 5, 10, 8) X

(30, 35, 40, 38) -> (15, 20, 25, 23) 0

 

그러면 미리 돌 수 있는 사이클은 다 돌았다. 이제 직접 사이클을 돌릴 시간이다.

 

코드


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

public class Solution {

	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringBuilder sb = new StringBuilder();
		int[] code = new int[8];
		
		for (int i = 1; i <= 10; i++) {
			int minNum = Integer.MAX_VALUE, sub = 0;
			br.readLine();
			StringTokenizer st = new StringTokenizer(br.readLine());
			
			//입력받으면서 최솟값 구하기
			for (int j = 0; j < 8; j++) {
				code[j] = Integer.parseInt(st.nextToken());
				if(code[j] < minNum) minNum = code[j];
			}
			
			//최솟값보다 작은 15의 배수 구하기
			sub = minNum/15*15;	
			if(minNum%15 == 0){sub -= 15;		
				System.out.println(i+" "+minNum);
			}
			//각 수에서 15의 배수 빼기
			for (int j = 0; j < 8; j++) {
				code[j] -= sub;
			}
			
			//0이 나올때 까지 사이클 돌기
			int minus = 0, index = -1;
			do {
				if(++minus == 6) minus = 1;
				index = (index+1)%8;
				code[index] -= minus;
			} while (code[index] > 0);
			code[index] = 0;
			
			sb.append("#"+i+" ");
			for (int j = index+1; j <= index+8; j++) {
				sb.append(code[j%8]+" ");
			}
			sb.append("\n");
		}
		System.out.println(sb.toString());
	}

}

 

'코딩테스트 > SWEA' 카테고리의 다른 글

SWEA 1251 : 하나로  (0) 2021.04.16