어떤 국가에서는 자국 내 방송국에서 스파이가

어떤 국가에서는 자국 내 방송국에서 스파이가
※ 문제에 대한 저작권은 SW Expert Academy에 있습니다.

💡 출처


https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AV15JEKKAM8CFAYD 

SW Expert Academy

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

swexpertacademy.com

어떤 국가에서는 자국 내 방송국에서 스파이가

💡 문제


[설명]

#1240번 단순 2진 암호 코드의 응용문제라고 할 수 있다.

https://coderand.tistory.com/entry/SWEA-1240-%EB%8B%A8%EC%88%9C-2%EC%A7%84-%EC%95%94%ED%98%B8%EC%BD%94%EB%93%9C

[SWEA] #1240 - 단순 2진 암호코드

💡 출처 https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AV15FZuqAL4CFAYD SW Expert Academy SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요! swexp..

coderand.tistory.com

어떤 국가에서는 자국 내 방송국에서 스파이가

💡 아이디어


#1240번 문제는 암호 코드의 길이가 정해져 있었다면 이번 문제는 가변적이며 2진 코드가 아닌 16진수의 코드이다.

그렇기 때문에 일단은 16진수의 코드를 2진수의 코드로 변환해야 한다.

그 후 코드의 시작은 0, 끝은 1이라는 특성을 이용해 암호 코드의 1과 0의 비율을 계산한다.

이 비율과 맞는 숫자가 있다면 배열에 넣고 #1240번 문제와 같이 해독을 하면 문제를 해결할 수 있다.

💡 소스코드


package SWEA;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class SWEA_P1242_암호코드_스캔 {
	static int Hex[][] = { { 0, 0, 0, 0 }, // 0
			{ 0, 0, 0, 1 }, // 1
			{ 0, 0, 1, 0 }, // 2
			{ 0, 0, 1, 1 }, // 3
			{ 0, 1, 0, 0 }, // 4
			{ 0, 1, 0, 1 }, // 5
			{ 0, 1, 1, 0 }, // 6
			{ 0, 1, 1, 1 }, // 7
			{ 1, 0, 0, 0 }, // 8
			{ 1, 0, 0, 1 }, // 9
			{ 1, 0, 1, 0 }, // A
			{ 1, 0, 1, 1 }, // B
			{ 1, 1, 0, 0 }, // C
			{ 1, 1, 0, 1 }, // D
			{ 1, 1, 1, 0 }, // E
			{ 1, 1, 1, 1 } // F
	};

	static int[][][] CODE = new int[4][3][4];

	public static void main(String[] args) throws Exception {
		System.setIn(new FileInputStream("./SWEA_INPUT/SWEA_P1242_input.txt"));
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		int T = Integer.parseInt(br.readLine());

		init();

		for (int TC = 1; TC <= T; TC++) {
			StringTokenizer sz = new StringTokenizer(br.readLine());
			int row = Integer.parseInt(sz.nextToken());
			int col = Integer.parseInt(sz.nextToken());
			int[][] Bincode = new int[row][col * 4];
			String preline = "";

			for (int i = 0; i < row; i++) {
				String line = br.readLine();

				if (line.split("0").length == 0 && line.contains(preline))//0으로 채워져 있거나 이전 line과 같다면 continue
					continue;
				
				else
					preline = line;//아니라면 preline 재설정

				//16진수를 2진수로 변환
				for (int j = 0; j < col; j++) {
					int c = line.charAt(j);

					if (c <= '9' && c >= '0')
						c = c - '0';
					else
						c = c - 'A' + 10;

					for (int k = 0; k < 4; k++)
						Bincode[i][j * 4 + k] = Hex[c][k];
				}
			}

			System.out.println("#" + TC + " " + Encode(Bincode, row, col));
		}
		br.close();
	}

	//0~9를 나타내는 코드의 비율 초기화
	public static void init() {
		CODE[1][0][0] = 0;
		CODE[1][1][0] = 1;
		CODE[0][1][1] = 2;
		CODE[3][0][0] = 3;
		CODE[0][2][1] = 4;
		CODE[1][2][0] = 5;
		CODE[0][0][3] = 6;
		CODE[2][0][1] = 7;
		CODE[1][0][2] = 8;
		CODE[0][0][1] = 9;
	}

	public static int Encode(int[][] Bincode, int row, int col) {
		int idx = 7;
		int[] code = new int[8];
		int result = 0;

		for (int i = 1; i < row; i++) {
			for (int j = col * 4 - 1; j >= 0; j--) {
				if (Bincode[i][j] == 1 && Bincode[i - 1][j] == 0) {//현재 지점과 이전 라인의 지점이 다른지 확인(중복제거)
					int x, y, z;
					x = y = z = 0;

					//끝에서 1의 개수 카운트
					while (Bincode[i][j] == 1) {
						z++;
						j--;
					}

					////끝에서 0의 개수 카운트
					while (Bincode[i][j] == 0) {
						y++;
						j--;
					}

					//끝에서 1의 개수 카운트
					while (Bincode[i][j] == 1) {
						x++;
						j--;
					}
					
					//끝에서 0의 개수 카운트
					while (Bincode[i][j] == 0 && j > 0) {
						j--;
					}

					j++;

					int min = Math.min(Math.min(x, y), z);//가장 작은 숫자로

					//나눠서 비율을 찾아냄
					x /= min;
					y /= min;
					z /= min;

					code[idx--] = CODE[x - 1][y - 1][z - 1];//code배열에 넣음

					if (idx == -1) {
						int sum = (code[0] + code[2] + code[4] + code[6]) * 3 + code[1] + code[3] + code[5] + code[7];

						if (sum % 10 == 0)
							for (int k = 0; k < code.length; k++)
								result += code[k];

						idx = 7;
					}
				}
			}
		}
		return result;
	}
}

💡 결과


어떤 국가에서는 자국 내 방송국에서 스파이가

암호 코드의 시작이 0, 끝이 1이라는 특징만 잘 찾아낸다면 쉽게 해결할 수 있는 문제였다.

하지만, 그걸 캐치하는 게 쉽지만은 않아 꽤 머리를 썼던 문제였다.