8
H L L H L L L L
H H L H Y L L H
L H L H L L Y L
H L L H L H L L
H Y L H L L L L
L H L H H L H L
L L L H L L L L
L X L H L H L L
10
H L L H L L L L L L
H H L H Y L L H L L
L H L H L L Y L L L
H L L H L H L L L L
H Y L H X L H H L L
L H L H H L H L L L
L L L H L L L L L L
L L L H Y H L L L L
L L L H L H L L L L
L L L H H H L L L L
10
H L L H L L L L L L
H H L H Y L L H L L
L H L H L L Y L L L
H L L H L H L L L L
H Y L H L L H H L L
L H L H H L H L L L
L L L H L L L L L L
L L L H Y H L L L L
L L L H L H L L L L
X L L H H H L L L L
10
H L L H L L L L L L
H H L H Y L L H L L
L H L H L L Y L L L
H L L H L H L L L L
H Y L H L L H H L L
L H L H H L H L L L
L L L H L L L L L L
L L L H Y H L L L L
L L L H L H L L L L
L H H H X H H Y H L

 

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Scanner;

public class JanggiCannon {
	public static void main(String[] args) throws FileNotFoundException {
		System.setIn(new FileInputStream("res/sample_input.txt"));
		
		Scanner sc = new Scanner(System.in);
		
		int mapSize = 0;
		int[] cannonCoordinate = new int[2];
		Boolean findMyCannon = false;
		int problemN = 1;
		int result = 0;
		int resultH = 0;
		int resultV = 0;
		
		while(true) {
			try {
				mapSize = Integer.parseInt(sc.nextLine());	// 장기판의 크기를 입력 받는다. nextInt를 사용시 return 소거용 nextLine을 한 번 더 써야 하기 대문에 형변환을 사용함.
			} catch (Exception e) {
				break;
			}
			
			// 장기판 맵을 매트릭스 배열로 만든다.
			char[][] map = new char[mapSize][mapSize];
			
			// 장기판에 알을 담는다.
			for (int i = 0; i < mapSize; i++) {
				map[i] = sc.nextLine().replace(" ", "").toCharArray();
				
				// 장기판을 채우다 포가 나오면 위치를 기억한다.
				if (!findMyCannon) {	// 포의 위치를 찾으면 그 문제에서는 더이상 찾는 시도를 하지 않는다.
					for (int j = 0; j < mapSize; j++) {
						if (map[i][j] == 'X') {
							cannonCoordinate[0] = i;
							cannonCoordinate[1] = j;
							findMyCannon = true;
						}
					}
				}
			}
	
			// Step 1. 수평 계산.
			// 내 포("X")가 있는 수평줄의 문자열을 구한다.
			String horizontal = new String(map[cannonCoordinate[0]], 0, mapSize);
						
			// 계산 메소드에 넣는다.
			resultH = calcAttack(horizontal);
			
			// Step 2. 수직 계산.
			// 내 포("X")가 있는 수직줄의 문자열을 구한다.
			StringBuilder sbd = new StringBuilder();
			for (int i = 0; i < mapSize; i++) {
				sbd.append(map[i][cannonCoordinate[1]]);
			}
			String vertical = sbd.toString();

			// 계산 메소드에 넣는다.
			resultV = calcAttack(vertical);

			// Step 3. 결과 산출 및 다음 문제를 위한 초기화.
			result = resultH + resultV;
			
			System.out.printf("%d번째 문제의 답은 : %d \n", problemN, result);
			findMyCannon = false;
			problemN++;
			result = resultH = resultV = 0;
		}
	}
	
	private static int calcAttack(String line) {
		int result = 0;
		
		// Step 1. 상대 캐논("Y")을 기준으로 나눈다.
		String[] target = line.split("Y"); 
		// Step 2. 내 캐논("X")이 포함된 유효한 구간만 가져온다.
		int targetIndex = includingTargetIndex(target);
		// Step 3. 공백("L")을 제거한다.
		String targetList = target[targetIndex].replace("L", "");
		// Step 4. 계산을 위해 내 캐논("X")을 기준으로 2개의 구간으로 나눈다.
		String[] splitedTargetList = targetList.split("X");
		
		int target1 = 0;
		int target2 = 0;
		// 배열이 존재하지 않을 경우에 대한 예외처리.
		try {
			target1 = (splitedTargetList[0].isEmpty()) ? 0 : splitedTargetList[0].length() - 1;	// 배열이 비어있다면 0, 비어있지 않다면 알을 하나 건너 뛰어야 하니 개수 - 1을 리턴.
		} catch (Exception e) {
			// TODO: handle exception
		}
		try {
			target2 = (splitedTargetList[1].isEmpty()) ? 0 : splitedTargetList[1].length() - 1;
		} catch (Exception e) {
			// TODO: handle exception
		}

		return target1 + target2;
	}
	
	// 캐논("X")이 포함된 문자열의 인덱스를 찾는 메소드.
	private static int includingTargetIndex(String target[]) {
		int result = 0;
		while (result < target.length) {
			if (target[result].contains("X")) break;
			result++;
		}	
		return result;
	}
}



결과 : 

1번째 문제의 답은 : 1 
2번째 문제의 답은 : 1 
3번째 문제의 답은 : 5 
4번째 문제의 답은 : 3 

 

함수를 쓰는게 코딩 테스트에서 효율이 좋은지 나쁜지 모르겠다...

 

문자열을 여러번 더할 경우는 String 말고 StringBuffer나 StringBuilder를 써야 빠르다.

char[]로 가져오면 문자라 바로 확인이 가능하다.
String[]로 가져오면 for문을 돌려야 문자 확인이 가능하다.

배열이 비어있는지 확인하려면 null로는 불가능하고, isEmpty()isBlank()를 써야하는데 isEmpty()가 좀 더 구버전까지 지원한다.

XHH를 'X'를 기준으로 나누면 {빈 배열} + {HH} 이렇게 2개의 배열로 나뉜다.
HHX를 'X'를 기준으로 나누면 {HH} 이렇게 1개의 배열만 생긴다. 따라서 이 경우 배열이 존재하지 않기 때문에 이 결과를 가지고 무언가를 하려면 try ~ catch를 해줘야한다. ()

		try {
			target2 = (splitedTargetList[1].isEmpty()) ? 0 : splitedTargetList[1].length() - 1;
		} catch (Exception e) {
			// TODO: handle exception
		}

이 부분...

 

 

 

'개발자 > Algorithm' 카테고리의 다른 글

Prim's Algorithm  (0) 2020.09.21
Kruskal's Algorithm  (0) 2020.09.14
04. 토끼 잡기  (0) 2020.08.28
02. 수열 A와 수열 B가 같은지 확인하기  (0) 2020.08.24
01. 괄호 짝 유효 여부와 N번째 괄호 짝 찾기  (0) 2020.08.24

+ Recent posts