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

2021. 10. 15. 00:32SW Expert Academy

1

구분: 구현
언어: Java
전략:

  • 주어지는 16진수 수들을 문자열로 생각
  • 문자열을 4등분 해야한다- StringBuffer의 substring을 이용한다 - 상자가 4각형이기 떄문에 --> 그 만큼의 길이가 나온다 
  • 각 문자열을 ArrayList에 저장한다 - 이미 존재하면 넣지 않는다 
  • 정렬한다 - Collections.sort(arr, Collections.reverseOrder()) 이용하면 내림차순 정렬 가능
  • 16 진수로 변경한다 - Integer.valueOf(String str, 16)을 사용하면 쉽게 구할 수 있다. 

 


2. 코드

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Deque;
import java.util.LinkedList;
import java.util.ArrayList;

public class Solution {
	public static void main(String[] args) throws NumberFormatException, IOException {
		
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		int T = Integer.parseInt(br.readLine());
		for(int tc = 1; tc<=T; tc++) {
			
			StringTokenizer st = new StringTokenizer(br.readLine(), " ");
			int n = Integer.parseInt(st.nextToken());
			int k = Integer.parseInt(st.nextToken());
			int count = n/4;//한 숫자의 길이 
			String str = br.readLine();
			StringBuffer data = new StringBuffer(str);
			ArrayList<String> arr = new ArrayList<>();//만들어진 숫자들을 넣을 것
			
			for(int i = 0; i<count; i++) {//
				for(int j = 0; j<n; j+=count) {//한 숫자 길이만큼 점프해서 
					String strs = data.substring(j, j+count);//그 자리와, 숫자만큼을 자른다 -- 이것이 하나의 숫자
					//중복 확인
					if(!arr.contains(strs))
						arr.add(strs);
				}
				//마지막 글자를 맨 앞으로 옮기는 작업
				String last = data.substring(data.length()-1, data.length());
				data.insert(0, last);
				//옮긴 것은 지운다 
				data.deleteCharAt(data.length() - 1);
			}

			
			
			//정렬하기 - 내림 차순
			Collections.sort(arr, Collections.reverseOrder());
			
			//인덱스가 0부터 시작하니까
			String ans = arr.get(k-1);
			int result = toInt(ans, count);
			System.out.println("#"+tc+" "+result);
			
			
		}//test
	}//main
	
	private static int toInt(String str, int count) {
		int ans = 0;
		for(int i = 0; i<str.length(); i++) {
			char ch = str.charAt(i);
			
			//0~9사이 숫자라면
			if(ch-'0'>=0 && ch-'0'<10) {
				ans+=(ch-'0')*Math.pow(16, count-1-i);
			}
			
			//아니라면 각각 맞춰서 구한다
			else {
				if(ch=='A') {
					ans+=10*Math.pow(16, count-1-i);
				}
				else if(ch=='B') {
					ans+=11*Math.pow(16, count-1-i);
				}
				else if(ch=='C') {
					ans+=12*Math.pow(16, count-1-i);
				}
				else if(ch=='D') {
					ans+=13*Math.pow(16, count-1-i);
				}
				else if(ch=='E') {
					ans+=14*Math.pow(16, count-1-i);
				}
				else if(ch=='F') {
					ans+=15*Math.pow(16, count-1-i);
				}
			}
			
		}
		
		return ans;
		//return Integer.valueOf(str, 16); - 16진수로 변경하는 방법
	}
}

3.

  • 나는 처음에 큐를 이용하여 문제를 풀었다. 하지만 정답이지만 계속 RuntimeError가 발생하여서 다른 분의 방법을 참고하였다 - 훨씬 더 간단
  • 특히 16진수로 변경하는 것은 내장 라이브러리를 사용할 줄 모르고, 다 구했다 
  • ArrayList정렬하는 방법 또한 이번 기회에 알 수 있었다. 
  • 많은 것들을 배울 수 있었던 문제이다.

참고 나의 오류 코드 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Deque;
import java.util.LinkedList;
import java.util.ArrayList;

public class Solution{
	public static void main(String[] args) throws NumberFormatException, IOException {
		
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		int T = Integer.parseInt(br.readLine());
		for(int tc = 1; tc<=T; tc++) {
			
			StringTokenizer st = new StringTokenizer(br.readLine(), " ");
			int n = Integer.parseInt(st.nextToken());
			int k = Integer.parseInt(st.nextToken());
			int count = n/4;//한 숫자의 길이 
			String str = br.readLine();
			ArrayList<String> arr = new ArrayList<>();//만들어진 숫자들을 넣을 것
			Deque<Character> q = new LinkedList<>();
			for(int i = 0; i<str.length(); i++) {
				q.offer(str.charAt(i));
			}
	
			//숫자 만들기
			String num = "";
			int number;
			int index = 0;
			for(int l = 0; l<3; l++) {
				for(int j = 0; j<4; j++) {
					num = "";
					for(int i = 0; i<count; i++) {
						char a = q.pollFirst();
						num+=a;
						q.offer(a);
					}
					if(!arr.contains(num))
						arr.add(num);
				}
				char b = q.pollLast();
				q.offerFirst(b);
			}
			
	
			//정렬하기 - 내림 차순
			Collections.sort(arr, Collections.reverseOrder());
			
			//인덱스가 0부터 시작하니까
			String ans = arr.get(k-1);
			int result = toInt(ans, count);
			System.out.println("#"+tc+" "+result);
			
			
		}//test
	}//main
	
	private static int toInt(String str, int count) {
		int ans = 0;
		for(int i = 0; i<str.length(); i++) {
			char ch = str.charAt(i);
			
			//0~9사이 숫자라면
			if(ch-'0'>=0 && ch-'0'<10) {
				ans+=(ch-'0')*Math.pow(16, count-1-i);
			}
			
			//아니라면 각각 맞춰서 구한다
			else {
				if(ch=='A') {
					ans+=10*Math.pow(16, count-1-i);
				}
				else if(ch=='B') {
					ans+=11*Math.pow(16, count-1-i);
				}
				else if(ch=='C') {
					ans+=12*Math.pow(16, count-1-i);
				}
				else if(ch=='D') {
					ans+=13*Math.pow(16, count-1-i);
				}
				else if(ch=='E') {
					ans+=14*Math.pow(16, count-1-i);
				}
				else if(ch=='F') {
					ans+=15*Math.pow(16, count-1-i);
				}
			}
			
		}
		
		return ans;
		//return Integer.valueOf(str, 16); - 16진수로 변경하는 방법
	}
}