[BOJ] 1799 λΉ„μˆ

문제

문제 μ„€λͺ…

Baekjoon Online Judge - 1799번 λΉ„μˆ

μ„œμ–‘ μž₯기인 μ²΄μŠ€μ—λŠ” λŒ€κ°μ„  λ°©ν–₯으둜 움직일 수 μžˆλŠ” λΉ„μˆ(bishop)이 μžˆλ‹€. < κ·Έλ¦Ό 1 >κ³Ό 같은 μ •μ‚¬κ°ν˜• 체슀판 μœ„μ— B라고 ν‘œμ‹œλœ 곳에 λΉ„μˆμ΄ μžˆμ„ λ•Œ λΉ„μˆμ€ λŒ€κ°μ„  λ°©ν–₯으둜 움직여 O둜 ν‘œμ‹œλœ 칸에 μžˆλŠ” λ‹€λ₯Έ 말을 μž‘μ„ 수 μžˆλ‹€.

그런데 체슀판 μœ„μ—λŠ” λΉ„μˆμ΄ 놓일 수 μ—†λŠ” 곳이 μžˆλ‹€. < κ·Έλ¦Ό 2 >μ—μ„œ μ²΄μŠ€νŒμ— μƒ‰μΉ λœ 뢀뢄은 λΉ„μˆμ΄ 놓일 수 μ—†λ‹€κ³  ν•˜μž. 이와 같은 μ²΄μŠ€νŒμ— μ„œλ‘œκ°€ μ„œλ‘œλ₯Ό μž‘μ„ 수 없도둝 ν•˜λ©΄μ„œ λΉ„μˆμ„ λ†“λŠ”λ‹€λ©΄ < κ·Έλ¦Ό 3 >κ³Ό 같이 μ΅œλŒ€ 7개의 λΉ„μˆμ„ 놓을 수 μžˆλ‹€. μƒ‰μΉ λœ λΆ€λΆ„μ—λŠ” λΉ„μˆμ΄ 놓일 수 μ—†μ§€λ§Œ μ§€λ‚˜κ°ˆ μˆ˜λŠ” μžˆλ‹€.

μ •μ‚¬κ°ν˜• 체슀판의 ν•œ 변에 놓인 칸의 개수λ₯Ό 체슀판의 크기라고 ν•œλ‹€. 체슀판의 크기와 체슀판 각 칸에 λΉ„μˆμ„ 놓을 수 μžˆλŠ”μ§€ μ—†λŠ”μ§€μ— λŒ€ν•œ 정보가 μ£Όμ–΄μ§ˆ λ•Œ, μ„œλ‘œκ°€ μ„œλ‘œλ₯Ό μž‘μ„ 수 μ—†λŠ” μœ„μΉ˜μ— 놓을 수 μžˆλŠ” λΉ„μˆμ˜ μ΅œλŒ€ 개수λ₯Ό κ΅¬ν•˜λŠ” ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•˜μ‹œμ˜€.

μž…λ ₯

첫째 쀄에 체슀판의 크기가 주어진닀. 체슀판의 ν¬κΈ°λŠ” 10μ΄ν•˜μ˜ μžμ—°μˆ˜μ΄λ‹€. λ‘˜μ§Έ 쀄뢀터 μ•„λž˜μ˜ μ˜ˆμ™€ 같이 체슀판의 각 칸에 λΉ„μˆμ„ 놓을 수 μžˆλŠ”μ§€ μ—†λŠ”μ§€μ— λŒ€ν•œ 정보가 체슀판 ν•œ 쀄 λ‹¨μœ„λ‘œ ν•œ 쀄씩 주어진닀. λΉ„μˆμ„ 놓을 수 μžˆλŠ” κ³³μ—λŠ” 1, λΉ„μˆμ„ 놓을 수 μ—†λŠ” κ³³μ—λŠ” 0이 λΉˆμΉΈμ„ 사이에 두고 주어진닀.

좜λ ₯

첫째 쀄에 주어진 체슀판 μœ„μ— 놓을 수 μžˆλŠ” λΉ„μˆμ˜ μ΅œλŒ€ 개수λ₯Ό 좜λ ₯ν•œλ‹€.

풀이

ν•΄μ„€

λ°±νŠΈλž˜ν‚Ήμ„ μ—°μŠ΅ν•˜κΈ°μ— 쒋은 문제, 원리λ₯Ό μ΄ν•΄ν•˜κΈ° 맀우 μ–΄λ €μ› λ˜ 문제.

  1. μ²΄μŠ€νŒμ„ 흑, 백으둜 λ‚˜λˆ„μ–΄ 각각 2λ²ˆμ„ 체크해쀀닀.
  2. 흑, λ°± 각 κ²½μš°μ— λŒ€ν•΄μ„œλŠ” ν˜„μž¬ μ’Œν‘œκ°€ μ†ν•œ λŒ€κ°μ„ μ΄ 점유됐으면(쒌, 우 쀑 ν•˜λ‚˜λΌλ„) 카운트 λ³€μˆ˜λ₯Ό μ¦κ°€ν•˜μ§€ μ•Šκ³  μž¬κ·€νƒ€κ³ , μ μœ λ˜μ§€ μ•Šμ•˜μœΌλ©΄ 카운트 λ³€μˆ˜λ₯Ό μ¦κ°€ν•˜μ—¬ μž¬κ·€λ₯Ό νƒœμš΄λ‹€.

    • λŒ€κ°μ„  점유 μ—¬λΆ€λŠ” 쒌, 우 λŒ€κ°μ„ μ˜ 기쀀점을 key둜 ν•˜κ³ , 점유 μ—¬λΆ€λ₯Ό value둜 ν•˜λŠ” 맡으둜 관리.
    • λŒ€κ°μ„  기쀀점은 ν˜„μž¬ μ’Œν‘œμ™€ λŒ€κ°μ„  μ’Œν‘œ κ°’μ˜ 차이가 (N-1)κ³Ό (N+1)μž„μ—μ„œ μ°©μ•ˆν•¨.
    • 쒌둜 ν–₯ν•˜λŠ” λŒ€κ°μ„ () 기쀀점은 ν˜„μž¬ μ’Œν‘œμ—μ„œ (N+1)λ§ŒνΌμ„ μ΅œλŒ€λ‘œ μ°¨κ°ν•œ 점인데, ν–‰μ’Œν‘œ * (N+1)λ§ŒνΌμ„ λΊ€ 점으둜 섀정함.
    • λ§ˆμ°¬κ°€μ§€λ‘œ 우둜 ν–₯ν•˜λŠ” λŒ€κ°μ„ (/) 기쀀점은 ν˜„μž¬ μ’Œν‘œμ—μ„œ (N-1)λ§ŒνΌμ„ μ΅œλŒ€λ‘œ μ°¨κ°ν•œ 점인데, ν–‰μ’Œν‘œ * (N-1)λ§ŒνΌμ„ λΊ€ 점으둜 섀정함.
  3. μž¬κ·€λ₯Ό νƒˆ λ•ŒλŠ” 열이 경계λ₯Ό λ„˜μ–΄κ°ˆ 경우 행을 μ¦κ°€μ‹œν‚¨λ‹€.
  4. κΈ°μ € 쑰건인 ν–‰ 경계에 λ„λ‹¬ν•˜λ©΄ 흑, λ°± 여뢀에 따라 카운트 λ³€μˆ˜λ₯Ό μ΅œλŒ“κ°’μœΌλ‘œ κ°±μ‹ ν•œλ‹€.

μ‹œν–‰μ°©μ˜€

  • μ²˜μŒμ—” κ·Έλ¦¬λ””μ²˜λŸΌ λͺ¨λ“  μ’Œν‘œμ— λŒ€ν•΄ λŒ€κ°μ„ μ— μœ„μΉ˜ν•œ λΉ„μˆμ— 영ν–₯을 μ£ΌλŠ” 개수λ₯Ό μ„Έ κ·Έ μˆ˜κ°€ 적은 μ’Œν‘œλ₯Ό μš°μ„ μ μœΌλ‘œ ν¬ν•¨ν•˜λŠ” λ°©μ‹μœΌλ‘œ ν’€μ–΄ ν‹€λ¦Ό. 그런데 μ™œ κ·Έλ¦¬λ””λ‘œ ν’€λ©΄ μ•ˆλ˜λŠ”μ§€λŠ” 잘 λͺ¨λ₯΄κ² λ‹€.. μ•„λ§ˆ κ·Έλ¦¬λ””λ‘œ ν’€μ—ˆμ„ λ•Œ 미처 ν¬ν•¨ν•˜μ§€ λͺ»ν•˜λŠ” μ’Œν‘œκ°€ μžˆμ„ 것 κ°™λ‹€.
  • λͺ¨λ“  κ°€λŠ₯ν•œ μ’Œν‘œμ— λŒ€ν•΄ λΉ„μˆμ²˜λ¦¬ ν–ˆλ‹€, μ•ˆν–ˆλ‹€ ν•˜λŠ” λ°©μ‹μœΌλ‘œ ν’€μ—ˆμœΌλ‚˜ 2^(NxN)의 μ‹œκ°„ λ³΅μž‘λ„λ‘œ 인해 μ‹œκ°„μ΄ˆκ³Ό 뜸.
  • ν˜„μž¬ μ’Œν‘œλ₯Ό ν¬ν•¨ν•˜λŠ” λŒ€κ°μ„ μ΄ μ μœ λ˜μ—ˆλŠ”μ§€ μ—¬λΆ€λ‘œ ν’€μ—ˆλŠ”λ°λ„ μ‹œκ°„μ΄ˆκ³Ό.. λŒ€κ°μ„  + ν‘λ°±μœ„μΉ˜λ‘œ 해결함. 이 ν’€μ΄μ—μ„œλ„ λͺ‡λ²ˆμ˜ μ‹œν–‰μ°©μ˜€κ°€ μžˆμ—ˆλŠ”λ°β€¦

    • ν˜„μž¬ μ’Œν‘œμ— λŒ€ν•΄ λΉ„μˆ 처리λ₯Ό ν•œ λ’€ μž¬κ·€ 타고 λ‹€μŒμœΌλ‘œ λ„˜μ–΄κ°ˆ λ•Œ λ‹€μ‹œ (0,0) μœ„μΉ˜λΆ€ν„° νƒμƒ‰ν•˜λ‹€λ³΄λ‹ˆ μ—¬μ „νžˆ μ‹œκ°„μ΄ˆκ³Όκ°€ λ–΄λ‹€.
    • (0,0) λΆ€ν„°κ°€ μ•„λ‹ˆλΌ ν˜„μž¬ μ’Œν‘œ 이후뢀터 νƒμƒ‰ν–ˆμ–΄μ•Ό ν–ˆλ‹€.
    • λ°±νŠΈλž˜ν‚Ήμ΄λΌλŠ” 것이 ν˜„μž¬ λ„λ‹¬ν•˜κΈ°κΉŒμ§€λŠ” λ¬Έμ œκ°€ μ—†μ—ˆλ‹€λŠ” 의미이고, μž¬κ·€λ₯Ό 타고 λ„˜μ–΄κ°”μ„ λ•Œ λ¬Έμ œκ°€ 생기면 더 확인할 ν•„μš”κ°€ μ—†μ–΄ λ˜λŒμ•„κ°€λŠ” κ²ƒμ΄κΈ°λ•Œλ¬Έμ— μ²˜μŒλΆ€ν„° ν™•μΈν•˜λ©΄ μ•ˆλ˜λŠ” κ²ƒμ΄μ—ˆλŠ”λ° μ•„μ§κΉŒμ§€ λ°±νŠΈλž˜ν‚Ή κ΅¬ν˜„μ— μ΅μˆ™μΉ˜ μ•Šμ•„ ν‹€λ¦° 것 같닀…
    • λ°±νŠΈλž˜ν‚Ή λΆ€λΆ„μ—μ„œ μ—΄ 경계체크 λ¨Όμ €ν•˜κ³  ν–‰ 경계체크λ₯Ό ν•΄μ•Ό 기저쑰건에 도달할 수 μžˆλŠ”λ°(μ—΄ κ²½κ³„μ²΄ν¬μ—μ„œ 열이 경계λ₯Ό λ„˜μ–΄κ°€λ©΄ ν–‰++ ν•΄μ£Όλ―€λ‘œ) λ°˜λŒ€λ‘œ ν–ˆλ‹€κ°€ 기저쑰건에 λ„λ‹¬ν•˜μ§€ μ•Šμ•„ 계속 닡이 0이 λμ—ˆμŒ.

μ½”λ“œ

Java
import java.io.*;
import java.util.*;

public class BOJ_1799_λΉ„μˆ {
	static int N, blackScore, whiteScore;
	static int[][] map;
	static Map<Integer, Boolean> left = new HashMap<Integer, Boolean>();       // 쒌둜 ν–₯ν•˜λŠ” λŒ€κ°μ„  점유 μ—¬λΆ€
	static Map<Integer, Boolean> right = new HashMap<Integer, Boolean>();      // 우둜 ν–₯ν•˜λŠ” λŒ€κ°μ„  점유 μ—¬λΆ€
	
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		N = Integer.parseInt(br.readLine());
		
		// μž…λ ₯
		map = new int[N][N];
		for (int i=0; i<N; i++) {
			StringTokenizer st = new StringTokenizer(br.readLine());
			for (int j=0; j<N; j++) map[i][j] = Integer.parseInt(st.nextToken());
		}
		
		// 쒌, 우 λŒ€κ°μ„  점유 μ—¬λΆ€ μ΄ˆκΈ°ν™”
		for (int i=(-1)*(N-1); i<N; i++) left.put(i, false);              // 쒌둜 ν–₯ν•˜λŠ” λŒ€κ°μ„ 
		for (int range=N+(N-1), i=0; i<range; i++) right.put(i, false);   // 우둜 ν–₯ν•˜λŠ” λŒ€κ°μ„ 
		
		playBishop(0, 0, true, 0);     // 흑
		playBishop(0, 1, false, 0);    // λ°±
		System.out.println(blackScore + whiteScore);
	}

	// 흑, λ°± 체슀판 각각의 λΉ„μˆ 완탐
	private static void playBishop(int x, int y, boolean isBlack, int cnt) {
		// 열경계 체크
		if (y >= N) {
			x++;                      // μ—΄ 경계 λ„˜μ–΄κ°€λ©΄ 행을 증가
			y = y % 2 == 0 ? 1 : 0;   // 이전 μ—΄ μΈλ±μŠ€κ°€ 짝수이면 ν™€μˆ˜λ‘œ, ν™€μˆ˜μ΄λ©΄ 짝수둜
		}
		
		// 기저쑰건 : 행경계 체크
		if (x >= N) {
			// 카운트 μ΅œλŒ“κ°’μœΌλ‘œ κ°±μ‹ 
			if (isBlack) blackScore = Math.max(blackScore, cnt);
			else whiteScore = Math.max(whiteScore, cnt);
			return;
		}
		
		// μœ λ„νŒŒνŠΈ : ν˜„μž¬ μ’Œν‘œμ— λŒ€ν•΄ λΉ„μˆμ„ μ²˜λ¦¬ν–ˆλ‹€, μ•ˆν–ˆλ‹€ ν•˜λ©° 카운트 μ„ΈκΈ°
		int curPoint = x*N+y;
		int l = curPoint - x * (N+1);     // ν˜„μž¬ μ’Œν‘œκ°€ ν¬ν•¨λœ λŒ€κ°μ„  기쀀점(쒌)
		int r = curPoint - x * (N-1);     // ν˜„μž¬ μ’Œν‘œκ°€ ν¬ν•¨λœ λŒ€κ°μ„  기쀀점(우)
		
		// κ°€λŠ₯ν•œ μ’Œν‘œμ΄λ©° 쒌, 우 λŒ€κ°μ„ μ΄ μ μœ λ˜μ§€ μ•Šμ•˜μœΌλ©΄
		if (map[x][y]==1 && !left.get(l) && !right.get(r)) {
			left.put(l, true);                     // λŒ€κ°μ„  점유 ν‘œμ‹œν•˜κ³  
			right.put(r, true);
			playBishop(x, y+2, isBlack, cnt+1);    // 카운트 μ¦κ°€ν•˜μ—¬ μž¬κ·€νƒ
			left.put(l, false);                    // λŒ€κ°μ„  점유 ν•΄μ œν•˜κ³ 
			right.put(r, false);
		}
		playBishop(x, y+2, isBlack, cnt);          // 카운트 μ¦κ°€ν•˜μ§€ μ•Šμ€ 채 μž¬κ·€νƒ
	}
}

πŸ’‘

  • λ°±νŠΈλž˜ν‚Ή λ„ˆλ¬΄ μ–΄λ €μš΄ 것 κ°™λ‹€. λ°±νŠΈλž˜ν‚Ήμ΄λž‘ κ°€μ§€μΉ˜κΈ° μ—°μŠ΅ν•˜λŠ” 문제 많이 ν’€μ–΄μ•Όκ² λ‹€ μ§„μ§œβ€¦