코깽이의 코딩일기

SWEA 5658. [모의 SW 역량테스트] 보물상자 비밀번호 본문

PS/SWEA

SWEA 5658. [모의 SW 역량테스트] 보물상자 비밀번호

코깽이 2024. 5. 2. 15:58
반응형

Link

https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AWXRUN9KfZ8DFAUo&categoryId=AWXRUN9KfZ8DFAUo&categoryType=CODE&problemTitle=%EC%97%AD%EB%9F%89&orderBy=FIRST_REG_DATETIME&selectCodeLang=ALL&select-1=&pageSize=10&pageIndex=1

 

SW Expert Academy

SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!

swexpertacademy.com


문제


 

내가 제출한 코드

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

public class Main {
	static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
	static StringBuilder sb = new StringBuilder();
	static StringTokenizer st;

	static int n, k, answer;
	static Deque<Character> q;
	static Map<Character, Integer> map = new HashMap<>();
	static Set<Integer> data;
	public static void main(String[] args) throws Exception {
		initMap();
		int t = Integer.parseInt(br.readLine());
		for (int i = 1; i <= t; i++) {
			init();
			run();
			sb.append("#").append(i).append(" ").append(answer).append("\n");
		}
		System.out.println(sb);
	}

	private static void init() throws Exception {
		// 중복 x, 내림차순 정렬을 위한 TreeSet
		data = new TreeSet<>(Collections.reverseOrder());
		// 앞,뒤 핸들링을 위한 문자열을 구하기 위한 Deque
		q = new ArrayDeque<>();

		st = new StringTokenizer(br.readLine());
		n = Integer.parseInt(st.nextToken());
		k = Integer.parseInt(st.nextToken());

		char[] input = br.readLine().toCharArray();
		for (char output : input) {
			q.add(output);
		}
	}

	private static void run() {

		int size = n / 4;
		// 만들어지는 문자열의 크기를 넘어서는 연산들은 중복되는 값이 나오기에 제외
		while (size-- > 0) {
			for (int i = 0; i < 4; i++) {
				// 한변에 존재하는 문자열 크기만큼 자르기
				String str = slice();
				// 16진수 -> 10진수 변환
				modify(str);
			}
			// 회전하기
			turn();
		}
		
		int cnt = 1;
		for(int output : data) {
			if(cnt == k) {
				answer = output;
			}
			cnt++;
		}
		

	}

	private static String slice() {
		String str = "";
		// 만들어 질 수 있는 문자열의 크기는 n / 4 로 나눈 값이다.
		for (int i = 0; i < n / 4; i++) {
			char charData = q.poll();
			str += charData;
			q.add(charData);
		}
		return str;
	}

	private static void turn() {
		// 맨 뒤에서 하나 꺼내 맨 앞에 저장한다.
		q.addFirst(q.pollLast());
	}

	private static void modify(String str) {
		int len = str.length();
		int intData = 0;
		for (int i = 0; i < len; i++) {
			intData += map.get(str.charAt(i)) * Math.pow(16, len - i - 1);
		}
		data.add(intData);
	}

	private static void initMap() {
		// 16진수 연산을 편하게 하기 위한 HashMap;
		map.put('0', 0);
		map.put('1', 1);
		map.put('2', 2);
		map.put('3', 3);
		map.put('4', 4);
		map.put('5', 5);
		map.put('6', 6);
		map.put('7', 7);
		map.put('8', 8);
		map.put('9', 9);
		map.put('A', 10);
		map.put('B', 11);
		map.put('C', 12);
		map.put('D', 13);
		map.put('E', 14);
		map.put('F', 15);
	}
}

 

생각해낸 로직

1. 각 변에 만들어지는 문자열을 구한다.

2. 16진수로 저장되어있는 문자열을 10진수로 변환한다.

3. 연산을 편하게 하기 위해 HashMap에 연산에 사용될 16진수들을 저장해둔다.

4. 문자열의 크기만큼 회전 시킨 이후에는 중복되는 값이 만들어진다.
5, 즉, 문자열의 길이만큼한 회전 시키면서 문자열을 만들어낸다.

6. 중복된 값이 나올 수 도 있기에 TreeSet을 이용해서 중복을 제거하고 내림차순 저장하면서 바로 저장한다.

 


 

반응형