처음에 이 문제를 보았을 때 이해하기가 조금 난해했다.
막 복잡하게 되어 있는데 결국에 0,1로 이루어진 암호코드를 적절하게 뽑아내서 매칭 시키고 확인하는 문제였다.
1.매칭을 위한 정보 삽입
static String[] pw = {
"0001101", "0011001", "0010011","0111101","0100011","0110001",
"0101111","0111011","0110111","0001011"};
암호문은 우리에게 시작부터 주어짐으로 우리는 이걸 편하게 사용하기 위해서 미리 배열형태로 저장!
- 어디서부터 시작?
사실 처음에 엄청 난해했던 부분이 시작점을 찾는 것이었다!
암호코드들의 시작은 0인데 대부분 0으로 암호문이 가려져있어서 56개의 암호문을 뽑아내는 방법이 중요했다!
이걸 어떻게 찾아내나..하는 생각을 하다가 암호문들의 끝이 1인 특징을 찾아냈고 이를 이용하면 i가 시작하는 위치를 기준으로 56칸만큼만 생각하면 된다!
- 시작점을 찾았다면 8개씩 뽑자!
for(int i = 0 ; i < row; i++){
for(int j = col-1; j >=0 ; j--){
//1찾으면 그 때부터
if(board[i][j] == '1'){
//System.out.println(i + " " + j);
find = 1;
int cnt = 0;
String temp = "";
//j-56번 찰 때까지 8개씩 찾기
for(int k = j-55 ; k <= j;k++){
temp += board[i][k];
cnt++;
if(cnt == 7){
//System.out.println(temp);
//암호랑 대조하면서 숫자 하나씩 쌓기
for(int m = 0; m < 10; m++){
if(temp.equals(pw[m])){
answer += Integer.toString(m);
}
}
//answer += temp;
temp = "";
cnt = 0;
}
}
}
if(find == 1)
break;
}
if(find == 1)
break;
}
내가 생각해도 분명 더 좋은 방법이 있다..일단 문제를 해결하려고 하다보니 코드도 지저분하고 깔끔하게 구현하지는 못했다.
아무튼 조금 틀린 부분들은 반복문의 시작과 끝!
끝에서부터 처음 등장한 1이 j인덱스니까 그걸 기준으로 -55를 해준 게 시작점이다!
그리고 1을 찾았다면 flag를 두어서 더 이상 반복문이 못 돌도록한다. 행에서 1이 여러 번 검출될 수 있음을 방지한다.
만약 7개가 다 찼다면 암호문과 비교~
4.암호문이 맞는지 확인
//[(홀수 자리의 합 x 3) + (짝수 자리의 합) == 10의 배수 ] 구해라 모든 수의 합
int sumOdd = Integer.parseInt(String.valueOf(answer.charAt(0)-'0' + answer.charAt(2)-'0'+ answer.charAt(4)-'0'+answer.charAt(6)-'0'));
int sumEven = Integer.parseInt(String.valueOf(answer.charAt(1)-'0' + answer.charAt(3)-'0'+ answer.charAt(5)-'0'+answer.charAt(7)-'0'));
if((sumOdd*3 + sumEven) % 10 == 0)
System.out.println(sumEven + sumOdd);
else
System.out.println(0);
char[]형태로 저장해둔 값들을 int에 맞게 출력해준다!
여기서 잠깐 헷갈렸던게 String.valueOf를 사용하는 부분..사실 블로그를 쓰면서 생각하니까 이렇게 굳이할 필요가 없다..String에서 charAt으로char로 빼고 -'0'을 해서 int처럼 사용!
int sumOdd = answer.charAt(0)-'0' + answer.charAt(2)-'0'+ answer.charAt(4)-'0'+answer.charAt(6)-'0';
int sumEven =answer.charAt(1)-'0' + answer.charAt(3)-'0'+ answer.charAt(5)-'0'+answer.charAt(7)-'0'1;
사실 엄청 어렵다기보다 구현하는 게 복잡하다? 번거롭다? 문제였다.
일단 내가 제대로 생각 못한 부분은 코드의 뒷부분이 모두 1인 것을 빨리 발견하지 못했고, 뒤에서부터 탐색해서 1 찾기 후에 반복문에 시작과 끝 인덱스를 잘못 설정 등이 있다.
문제에 대해서 구현을 하는 게 생각보다 어렵고 번거로운 것 같다..어렵다 어려워 그래도 화이팅👍
import java.util.Scanner;
import java.io.FileInputStream;
class Solution
{
static String[] pw = {
"0001101", "0011001", "0010011","0111101","0100011","0110001",
"0101111","0111011","0110111","0001011"};
public static void main(String args[]) throws Exception
{
Scanner sc = new Scanner(System.in);
int T=sc.nextInt();
for(int test_case = 1; test_case <= T; test_case++)
{
System.out.print("#" + test_case + " ");
int row = sc.nextInt();
int col = sc.nextInt();
char[][] board = new char[row][col];
String answer = "";
for(int i = 0 ; i < row; i++){
String oneRow = sc.next();
for(int j = 0 ; j < col; j++){
board[i][j] = oneRow.charAt(j);
}
}
//오른쪽부터 시작해서 순회하면서 1찾기
int find = 0;
for(int i = 0 ; i < row; i++){
for(int j = col-1; j >=0 ; j--){
//1찾으면 그 때부터
if(board[i][j] == '1'){
//System.out.println(i + " " + j);
find = 1;
int cnt = 0;
String temp = "";
//j-56번 찰 때까지 8개씩 찾기
for(int k = j-55 ; k <= j;k++){
temp += board[i][k];
cnt++;
if(cnt == 7){
//System.out.println(temp);
//암호랑 대조하면서 숫자 하나씩 쌓기
for(int m = 0; m < 10; m++){
if(temp.equals(pw[m])){
answer += Integer.toString(m);
}
}
//answer += temp;
temp = "";
cnt = 0;
}
}
}
if(find == 1)
break;
}
if(find == 1)
break;
}
//System.out.println(answer);
//[(홀수 자리의 합 x 3) + (짝수 자리의 합) == 10의 배수 ] 구해라 모든 수의 합
int sumOdd = answer.charAt(0)-'0' + answer.charAt(2)-'0'+ answer.charAt(4)-'0'+answer.charAt(6)-'0';
int sumEven =answer.charAt(1)-'0' + answer.charAt(3)-'0'+ answer.charAt(5)-'0'+answer.charAt(7)-'0';
//System.out.println(sumEven + " " + sumOdd);
if((sumOdd*3 + sumEven) % 10 == 0)
System.out.println(sumEven + sumOdd);
else
System.out.println(0);
}
}
}