본문 바로가기
알고리즘 문제풀이/백준

[백준 14499] 주사위 굴리기(JAVA/C++)

by 소보루:-) 2020. 3. 10.

 

https://www.acmicpc.net/problem/14499

 

14499번: 주사위 굴리기

첫째 줄에 지도의 세로 크기 N, 가로 크기 M (1 ≤ N, M ≤ 20), 주사위를 놓은 곳의 좌표 x y(0 ≤ x ≤ N-1, 0 ≤ y ≤ M-1), 그리고 명령의 개수 K (1 ≤ K ≤ 1,000)가 주어진다. 둘째 줄부터 N개의 줄에 지도에 쓰여 있는 수가 북쪽부터 남쪽으로, 각 줄은 서쪽부터 동쪽 순서대로 주어진다. 주사위를 놓은 칸에 쓰여 있는 수는 항상 0이다. 지도의 각 칸에 쓰여 있는 수는 10을 넘지 않는 자연수 또는 0이다. 마

www.acmicpc.net

 

 

7달 전에 C++로 풀었을 때는 가로 세로 배열을 각각 만들었다.

이번에 자바로 풀 때는 좀 더 간단하게 일차원 배열 하나만 써서 구현했다.

sysout출력문을 써봤다가 출력량이 많아서 StringBuilder를 이용했더니 메모리랑 시간이 좀 더 줄었다.

 

[JAVA]

import java.util.Scanner;

public class Main {

	static int N,M, x,y,K;
	static int[][] map;
	static int[] dx= {0,0,-1,1};//우좌상하 0123
	static int[] dy= {1,-1,0,0};
	static int[] dice= {0,0,0,0,0,0,0};
	static StringBuilder sb=new StringBuilder();
	
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		N=sc.nextInt();
		M=sc.nextInt();
		x=sc.nextInt();
		y=sc.nextInt();
		K=sc.nextInt();
		map=new int[N][M];
		for(int i=0; i<N; i++) {
			for(int j=0; j<M; j++) {
				map[i][j]=sc.nextInt();
			}
		}
		for(int i=0; i<K; i++) {
			change(sc.nextInt()-1);
		}
		System.out.println(sb.toString());
		
	}
	private static void change(int dir) {
		int nx=x+dx[dir];
		int ny=y+dy[dir];
		if(nx<0||ny<0||nx>=N||ny>=M) return;
		int[] copy=dice.clone();
		if(dir==0) {//우
			dice[6]=copy[3];
			dice[3]=copy[1];
			dice[1]=copy[4];
			dice[4]=copy[6];
		}else if(dir==1) {//좌
			dice[6]=copy[4];
			dice[3]=copy[6];
			dice[1]=copy[3];
			dice[4]=copy[1];
		}else if(dir==2) {//상
			dice[2]=copy[1];
			dice[1]=copy[5];
			dice[5]=copy[6];
			dice[6]=copy[2];
		}else if(dir==3) {//하
			dice[1]=copy[2];
			dice[2]=copy[6];
			dice[6]=copy[5];
			dice[5]=copy[1];
		}
		if(map[nx][ny]==0) {
			map[nx][ny]=dice[6];
		}else {
			dice[6]=map[nx][ny];
			map[nx][ny]=0;
		}
		sb.append(dice[1]+"\n");
		x=nx; y=ny;
	}

}

 

 

 

[C++]

#include <iostream>
#include <queue>

using namespace std;

int N, M, startX, startY, K;
int map[20][20];
int dx[4] = { 0,0,-1,1 };
int dy[4] = { 1,-1,0,0 };
int dice_x[4];//주사위가로
int dice_y[4];//주사위세로
queue <int> q;

void Rotate(int dir) {
	if (dir == 1) {//동
		int temp;
		temp = dice_x[0];
		dice_x[0] = dice_x[1];
		dice_x[1] = dice_x[2];
		dice_x[2] = dice_x[3];
		dice_x[3] = temp;
		dice_y[1] = dice_x[1];
		dice_y[3] = dice_x[3];
	}
	if (dir == 2) {//서
		int temp;
		temp = dice_x[3];
		dice_x[3] = dice_x[2];
		dice_x[2] = dice_x[1];
		dice_x[1] = dice_x[0];
		dice_x[0] = temp;
		dice_y[1] = dice_x[1];
		dice_y[3] = dice_x[3];
	}
	if (dir == 3) {//북
		int temp;
		temp = dice_y[3];
		dice_y[3] = dice_y[2];
		dice_y[2] = dice_y[1];
		dice_y[1] = dice_y[0];
		dice_y[0] = temp;
		dice_x[1] = dice_y[1];
		dice_x[3] = dice_y[3];
	}
	if (dir == 4) {//남
		int temp;
		temp = dice_y[0];
		dice_y[0] = dice_y[1];
		dice_y[1] = dice_y[2];
		dice_y[2] = dice_y[3];
		dice_y[3] = temp;
		dice_x[1] = dice_y[1];
		dice_x[3] = dice_y[3];
	}

}
void Solve() {
	int x = startX;
	int y = startY;
	while (!q.empty()) {
		int dir = q.front(); q.pop(); //1동 2서 3북 4남
		int nx = x + dx[dir - 1];
		int ny = y + dy[dir - 1];
		//범위 벗어날 경우 명령 무시
		if (nx < 0 || ny < 0 || nx >= N || ny >= M)
			continue;
		Rotate(dir);
		//바닥값은 dice_y[1](dice_x[1]), 윗값은 dice_y[3]
		if (map[nx][ny] == 0) {
			map[nx][ny] = dice_y[1];
		}
		else if(map[nx][ny]){
			dice_y[1] = map[nx][ny];
			dice_x[1] = map[nx][ny];
			map[nx][ny] = 0;
		}
		cout << dice_y[3] << endl;
		//x,y값 갱신
		x = nx, y = ny;

	}
}
int main() {
    ios::sync_with_stdio(0); 
    cin.tie(0); 
    cout.tie(0); 

	cin >> N >> M >> startX >> startY >> K;

	for (int i = 0; i < N; i++)for (int j = 0; j < M; j++) {
		cin >> map[i][j];
	}
	for (int i = 0; i < K; i++) {
		int val;
		cin >> val;
		q.push(val);
	}
	Solve();
	return 0;
}

댓글