본문 바로가기
알고리즘/Backjoon

1986번 : 체스

by 뚱키 2022. 3. 2.
728x90
난이도 Silver2
링크 https://www.acmicpc.net/problem/1986

문제 사진


풀이.

하라는 대로 하면 되는 '구현' 문제

P는 걸림돌 Q는 8방향 K는 각 지정좌표 표시했다.

Q==1 K==2 P==3 으로 표시 후 갈 수 있는 좌표에 4를 입력해주었다.

결국 모든 로직 실행 뒤 밟지않은 곳(좌표의 값이 0인 곳) 을 세주면 답이 나오도록 설계하였다.


소스코드.

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

public class B1986 {
	static int N,M;
	public static void main(String[] args) throws IOException{
		BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer stz=new StringTokenizer(br.readLine());
		
		N=Integer.parseInt(stz.nextToken());
		M=Integer.parseInt(stz.nextToken());
		
		
		int[][] map=new int[N+1][M+1];
		
		// 1 = Q , 2 = K , 3 = P
		for(int i=1;i<=3;i++) {
			stz=new StringTokenizer(br.readLine());
			int KQP=Integer.parseInt(stz.nextToken());
			
			for(int j=0;j<KQP;j++) {
				int x=Integer.parseInt(stz.nextToken());
				int y=Integer.parseInt(stz.nextToken());
				
				map[x][y]=i;
			}
		}
		
		for(int i=1;i<=N;i++) {
			for(int j=1;j<=M;j++) {
				if(map[i][j]==1) {
					checkQueen(map, i, j);
				}
				if(map[i][j]==2) {
					checkKnight(map, i, j);
				}
			}
		}
		
		int count=0;
		
		for(int i=1;i<=N;i++) {
			for(int j=1;j<=M;j++) {
				if(map[i][j]==0) {
					count++;
				}
			}
		}
		
		System.out.println(count);
	}
	
	public static int[][] checkQueen(int[][] map,int x,int y){
		int rdx=x;
		int rdy=y;	
		//가로
		rdx=x;
		rdy=y;		
		//왼쪽
		while(true) {
			rdy-=1;
			if(rdy<0 ||(map[rdx][rdy]==1) || (map[rdx][rdy]==2)|| (map[rdx][rdy]==3)) {
				break;
			}
			map[x][rdy]=4;
		}
		
		//오른쪽
		rdx=x;
		rdy=y;	
		while(true) {
			rdy+=1;
			if(rdy>=M+1 ||(map[rdx][rdy]==1) || (map[rdx][rdy]==2)|| (map[rdx][rdy]==3)) {
				break;
			}
			map[x][rdy]=4;
		}
		//세로
		//위
		rdx=x;
		rdy=y;	
		while(true) {
			rdx-=1;
			if(rdx<0 ||(map[rdx][rdy]==1) || (map[rdx][rdy]==2)|| (map[rdx][rdy]==3)) {
				break;
			}
			map[rdx][y]=4;
		}
		//아래
		rdx=x;
		rdy=y;	
		while(true) {
			rdx+=1;
			if(rdx>=N+1 ||(map[rdx][rdy]==1) || (map[rdx][rdy]==2)|| (map[rdx][rdy]==3)) {
				break;
			}
			map[rdx][y]=4;
		}
		
		
		//대각
		rdx=x;
		rdy=y;		
		//왼대각
		//4사분면
		while(true) {
			rdx-=1;
			rdy-=1;
			if(rdx<0 || rdy<0 ||(map[rdx][rdy]==1) || (map[rdx][rdy]==2)|| (map[rdx][rdy]==3)) {
				break;
			}
			
			map[rdx][rdy]=4;
		}
		
		rdx=x;
		rdy=y;
		//2사분면
		while(true) {
			rdx+=1;
			rdy+=1;
			if(rdx>=N+1 || rdy>=M+1 ||(map[rdx][rdy]==1) || (map[rdx][rdy]==2)|| (map[rdx][rdy]==3)) {
				break;
			}
			
			map[rdx][rdy]=4;
		}
		
		
		//우대각
		//1사분면
		rdx=x;
		rdy=y;
		while(true) {
			rdx-=1;
			rdy+=1;
			if(rdx<0 || rdy>=M+1 ||(map[rdx][rdy]==1) || (map[rdx][rdy]==2)|| (map[rdx][rdy]==3)) {
				break;
			}
			
			map[rdx][rdy]=4;
		}
		
		
		//3사분면
		rdx=x;
		rdy=y;
		while(true) {
			rdx+=1;
			rdy-=1;
			if(rdx>=N+1 || rdy<0 ||(map[rdx][rdy]==1) || (map[rdx][rdy]==2)|| (map[rdx][rdy]==3)) {
				break;
			}
			
			map[rdx][rdy]=4;
		}
		
		
		
		return map;
	}
	public static int[][] checkKnight(int[][] map,int x,int y){
		int[] dx={2,2,1,1,-1,-1,-2,-2};
		int[] dy= {-1,1,-2,2,-2,2,-1,1};
		
		for(int i=0;i<8;i++) {
			int rdx=x+dx[i];
			int rdy=y+dy[i];
			if(rdx<1 || rdy<1 || rdx>=N+1 || rdy>=M+1 || map[rdx][rdy]!=0) {
				continue;
			}
			
			map[rdx][rdy]=4;
		}
		return map;
	}

}

중간중간 rdx->x rdy->y 로 바꿔줘야하는 코드가 있다.  (값은 같지만, 가독성을 높이기 위하여)

감안하고 보셨으면 합니다.


후기.

구현은 레고 조립하는 맛이 있는 것 같다. 하라는 대로 하면 풀리기 때문에 재미있다.

하지만 시간 제한이 있는 코딩테스트라면 ㅋㅋ..

728x90

'알고리즘 > Backjoon' 카테고리의 다른 글

B16948 : 데스 나이트  (0) 2022.02.23
18258 : 큐 2  (0) 2022.02.22
B3085 : 사탕 게임  (0) 2022.02.14
B18108: 1998년생인 내가 태국에서는 2541년생?!  (0) 2022.02.12
5567번: 결혼식  (0) 2020.02.23

댓글