https://softeer.ai/practice/6255
1. 아이디어
문자열을 통한 구현 문제로 열심히 구현하면 간단하게 해결할 수 있다.
2. 문제풀이
먼저 주어진 메시지로 문자를 두 글자씩 나누는 조건을 구현했는데 for문에서 인덱스를 i+=2로 두 칸씩 건너가는 방식으로 두 글자를 뽑아서 다르면 StringBuilder에 넣고 같으면 X가 아니면 X를 넣고 X면 Q를 넣도록 했다. 이때 X 또는 Q를 넣으면 두번째 글자가 X 또는 Q로 대체되는 것이므로 i--로 인덱스를 하나 줄이도록 했다. 또 이때 삽입한 문자의 수를 저장해서 이후 기존 메시지와 삽입한 문자 수의 합이 홀수면 뒤에 X를 추가로 넣는 조건을 구현했다.
주어진 키를 표로 변환하는 것은 변환 후 남은 칸은 다시 A부터 없는 알파벳을 채워야하는데 이 구현을 편하게 하기 위해 미리 주어진 키 뒤에 A부터 J를 제외한 Z까지를 더한 후 이 키로 표를 채웠다. 이후 표의 정보로 각 알파벳의 위치를 저장한 맵까지 생성했다.
마지막으로 두 글자씩 뽑아서 암호화를 하면 되는데 두 글자의 위치를 맵에서 뽑아서 비교만하면 간단하게 구현할 수 있다.
3. 코드
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringBuilder sb = new StringBuilder();
char[] message = br.readLine().toCharArray();
char[] newMessage = makeNewMessage(message);
// 구현의 편의를 위해 미리 J를 제외한 알파벳을 붙여서 키를 생성
char[] key = (br.readLine() + "ABCDEFGHIKLMNOPQRSTUVWXYZ").toCharArray();
// 주어진 키를 변환한 표
char[][] map = init(key);
// key에 알파벳, value에 표에서의 위치를 저장한 맵
Map<Character, int[]> posMap = init(map);
for (int i = 0; i < newMessage.length; i += 2) {
char c1 = newMessage[i];
char c2 = newMessage[i + 1];
int rowC1 = posMap.get(c1)[0];
int colC1 = posMap.get(c1)[1];
int rowC2 = posMap.get(c2)[0];
int colC2 = posMap.get(c2)[1];
// 규칙 1
if (rowC1 == rowC2) sb.append(map[rowC1][(colC1 + 1) % 5]).append(map[rowC2][(colC2 + 1) % 5]);
// 규칙 2
else if (colC1 == colC2) sb.append(map[(rowC1 + 1) % 5][colC1]).append(map[(rowC2 + 1) % 5][colC2]);
// 규칙 3
else sb.append(map[rowC1][colC2]).append(map[rowC2][colC1]);
}
bw.write(sb.toString());
bw.flush();
}
// 주어진 메시지를 두 글자씩 나누는 로직 적용
private static char[] makeNewMessage(char[] message) {
StringBuilder sb = new StringBuilder();
int cnt = 0;
for (int i = 0; i < message.length - 1; i += 2) {
char c1 = message[i];
char c2 = message[i + 1];
if (c1 != c2) {
sb.append(c1).append(c2);
} else {
if (c1 == 'X') sb.append(c1).append('Q');
else sb.append(c1).append('X');
cnt++;
i--;
}
}
// 마지막에 한 글자가 남는 경우
if ((message.length + cnt) % 2 == 1) sb.append(message[message.length - 1]).append('X');
return sb.toString().toCharArray();
}
// 주어진 키를 표로 변환
private static char[][] init(char[] key) {
char[][] map = new char[5][5];
boolean[] visited = new boolean[26];
int idx = 0;
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
while (visited[key[idx] - 'A']) {
idx++;
}
map[i][j] = key[idx];
visited[map[i][j] - 'A'] = true;
}
}
return map;
}
// 알바벳의 위치를 저장한 맵 반환
private static Map<Character, int[]> init(char[][] map) {
Map<Character, int[]> posMap = new HashMap<>();
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
posMap.put(map[i][j], new int[]{i, j});
}
}
return posMap;
}
}
4. 후기
'코딩테스트 준비 > 소프티어' 카테고리의 다른 글
[소프티어] 6248번 - 출퇴근길 [Java] (0) | 2025.02.10 |
---|---|
[소프티어] 6275번 - 로봇이 지나간 경로 [Java] (0) | 2025.02.07 |
[소프티어] 6257번 - 통근버스 출발 순서 검증하기 [Java] (0) | 2025.02.07 |
[소프티어] 6251번 - 업무 처리 [Java] (1) | 2025.02.06 |
[소프티어] 6250번 - 성적 평가 [Java] (0) | 2025.02.06 |