Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
206 changes: 206 additions & 0 deletions dongju/BOJ/Main_12100_2048easy.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
package BOJ;

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

public class Main_12100_2048easy {
static int N, max;
static int[][] map, copy;

public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

N = Integer.parseInt(br.readLine());

map = new int[N][N];
copy = new int[N][N];

max = Integer.MIN_VALUE;

for (int i = 0; i < N; i++) {
StringTokenizer tokens = new StringTokenizer(br.readLine());
for (int j = 0; j < N; j++) {
map[i][j] = Integer.parseInt(tokens.nextToken());
copy[i][j] = map[i][j];
max = Math.max(max, map[i][j]); //초기 최대값은 맵에서 가장 큰 값
}
}

perm(0, new int[5]);

System.out.println(max);
}

private static void perm(int cnt, int[] order) {//상하좌우 움직일 순서를 정함. 중복순열
if (cnt == 5) {
//순서대로 이동하기
for (int d = 0; d < 5; d++) {
move(order[d]); //이동 순서에 따라 이동
}

//카피배열을 처음 상태로 돌려줌
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
copy[i][j] = map[i][j];
}
}
return;
}

for (int i = 0; i < 4; i++) {
//상하좌우 움직일 순서를 정함
order[cnt] = i;
perm(cnt + 1, order);
}
}

private static void move(int d) {
//아래같은 경우 공백 없게 붙여준 다음 같은 값을 합쳐줘야함 그리고 다시 0없게 붙여줌
//2 2 4
//0 0 4
//2 2 4

//붙여줌 값 합침 붙여줌
//2 2 4 4 4 8 4 4 8
//2 2 4 => 0 0 0 => 0 0 4
//0 0 4 0 0 4 0 0 0

//공백없이 붙여주는 메서드
noZero(d);

//방향대로 값을 합치기 위한 부분
switch (d) {
case 0: //위로 움직임
//열로 탐색, 시작 인덱스는 0~N
for (int j = 0; j < N; j++) {//한 열씩 진행
for (int i = 0; i < N - 1; i++) {//첫번째부터 n-1까지 선택
if (copy[i][j] == copy[i + 1][j]) { //첫번째와 두번째가 같으면 합쳐주고 두번째를 비워줌
copy[i][j] += copy[i + 1][j];
copy[i + 1][j] = 0;
}
}
}
break;

case 1: //아래로 움직임
//열로 탐색
for (int j = 0; j < N; j++) {//한 열씩 값 수정
for (int i = N - 1; i > 0; i--) {//행 시작 인덱스는 N~0
if (copy[i][j] == copy[i - 1][j]) {
copy[i][j] += copy[i - 1][j];
copy[i - 1][j] = 0;
}
}
}
break;

case 2: //좌로 움직임
//행으로 탐색
for (int i = 0; i < N; i++) {//한 행씩 값 수정
for (int j = 0; j < N - 1; j++) {//시작 인덱스는 0~N
if (copy[i][j] == copy[i][j + 1]) {
copy[i][j] += copy[i][j + 1];
copy[i][j + 1] = 0;
}
}
}
break;

case 3: //우로 움직임
//열로 탐색
for (int i = 0; i < N; i++) {
for (int j = N - 1; j > 0; j--) {//행 시작 인덱스는 N~0
if (copy[i][j] == copy[i][j - 1]) {
copy[i][j] += copy[i][j - 1];
copy[i][j - 1] = 0;
}
}
}
break;
}

//다시 공백 없게 붙여줌
noZero(d);

//한번 움직일때마다 최대값 찾음
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
max = Math.max(max, copy[i][j]);
}
}
}

private static void noZero(int d) {
switch (d) {
case 0://위로 움직임
for (int j = 0; j < N; j++) {//한 열씩 값 수정
for (int i = 0; i < N - 1; i++) {//행의 0부터 N까지 첫번째 인덱스 정함
int idx = i + 1; //i의 다음 인덱스
if (copy[i][j] == 0) {//첫번째 인덱스가 0이라면 다음이 0이 아닐때까지 검사
while (idx < N) { //배열 범위를 벗어나지 않을 때까지 반복
if (copy[idx][j] != 0) { //0이 아니라면 0인 첫부분에 값 옮김
copy[i][j] = copy[idx][j];
copy[idx][j] = 0;
break;
}
idx++; //0이라면 다음 검색을 위해 인덱스 증가
}
}
}
}
break;
case 1:
for (int j = 0; j < N; j++) {//한 열씩 값 수정
for (int i = N - 1; i > 0; i--) {
int idx = i - 1;
if (copy[i][j] == 0) {//0이라면 다음이 0이 아닐때까지 검사해야함
while (idx >= 0) {
if (copy[idx][j] != 0) {
copy[i][j] = copy[idx][j];
copy[idx][j] = 0;
break;
}
idx--;
}
}
}
}
break;
case 2:
for (int i = 0; i < N; i++) {//한 열씩 값 수정
for (int j = 0; j < N - 1; j++) {
int idx = j + 1;
if (copy[i][j] == 0) {
while (idx < N) {
if (copy[i][idx] != 0) {
copy[i][j] = copy[i][idx];
copy[i][idx] = 0;
break;
}
idx++;
}
}
}
}
break;
case 3:
for (int i = 0; i < N; i++) {//한 열씩 값 수정
for (int j = N - 1; j > 0; j--) {
int idx = j - 1;
if (copy[i][j] == 0) {
while (idx >= 0) {
if (copy[i][idx] != 0) {
copy[i][j] = copy[i][idx];
copy[i][idx] = 0;
break;
}
idx--;
}
}
}
}
break;
}
}
}
155 changes: 155 additions & 0 deletions dongju/BOJ/Main_13460_구슬탈출2.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
package BOJ;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;

public class Main_13460_구슬탈출2 {

static int N, M; //배열 크기
static char[][] map;
static Point pos; //처음 빨간구슬, 파란구슬 저장할 위치

static int[] dr = {-1, 1, 0, 0}; //상하좌우 이동
static int[] dc = {0, 0, -1, 1};

static class Point {
//빨간구슬, 파란구슬, 총 이동 횟수 저장
int rx, ry, bx, by, cnt;

public Point() {
}

public Point(int rx, int ry, int bx, int by, int cnt) {
this.rx = rx;
this.ry = ry;
this.bx = bx;
this.by = by;
this.cnt = cnt;
}
}

public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer tokens = new StringTokenizer(br.readLine());

N = Integer.parseInt(tokens.nextToken());
M = Integer.parseInt(tokens.nextToken());

pos = new Point();
map = new char[N][M];

for (int i = 0; i < N; i++) {
String temp = br.readLine();
for (int j = 0; j < M; j++) {
map[i][j] = temp.charAt(j);
if (map[i][j] == 'R') {//빨간 구슬 위치 입력
pos.rx = i;
pos.ry = j;
} else if (map[i][j] == 'B') {//파란 구슬 위치 입력
pos.bx = i;
pos.by = j;
}
}
}

pos.cnt = 0; //초기 이동값 0

bfs();

}//end main

private static void bfs() {

Queue<Point> queue = new LinkedList<>();
queue.offer(pos);
boolean[][][][] v = new boolean[N][M][N][M]; //앞의 [][]는 빨간구슬 확인, 뒤의 [][]는 파란구슬 확인. 이 체크 안하면 계속 실행됨

while (!queue.isEmpty()) {
Point cur = queue.poll(); //현재 위치 가져옴
v[cur.rx][cur.ry][cur.bx][cur.by] = true; //방문했다 표시

if (cur.cnt >= 10) {//10회 이상 움직이면 -1
System.out.println(-1);
return;
}

for (int d = 0; d < 4; d++) {//4방으로 굴려봄

boolean red = false, blue = false; //어느 구슬이 빠졌는지 확인할 flag

//빨간공 먼저 굴림
int rx = cur.rx;
int ry = cur.ry;

while (map[rx + dr[d]][ry + dc[d]] != '#') {//벽 안 만날때까지
rx += dr[d]; //선택한 방향으로 인덱스 증가
ry += dc[d];
if (map[rx][ry] == 'O') {//구멍만나면 탈출
red = true; //빨간구슬이 빠졌다고 표시
break;
}
}

//파란공 굴림
int bx = cur.bx;
int by = cur.by;

while (map[bx + dr[d]][by + dc[d]] != '#') {//벽 안 만날때까지
bx += dr[d];
by += dc[d];
if (map[bx][by] == 'O') {//구멍만나면 탈출
blue = true; //파란구슬 빠졌다고 표시
break;
}
}

if (blue) {//파란공이 빠졌는지 먼저 체크. 빠졌으면 아래 진행 안 하고 다음 방향으로 넘어감
continue;
}
if (red) {//파란공 안 빠지고, 빨간공이 빠졌으면 결과 출력후 종료. bfs이기 때문에 최소 횟수가 됨
System.out.println(cur.cnt + 1);
return;
}

if (rx == bx && ry == by) { //빨간구슬과 파란구슬이 같은 위치에 도착했다면, 처음 위치에서 어느쪽이 먼저 있는지 확인
switch (d) { //움직이는 방향에 따라서 도착위치 파악 가능
case 0: //위로 움직이는 방향. 열이 같음
if (cur.rx < cur.bx) //처음에 빨간파란구슬 위치 비교.
bx += 1; //도착지점 비교. 빨간공이 초기에 파란구슬보다 앞에 있다면 빨간공이 먼저 도착하기 때문에 파란공은 한칸 아래로 내려줌
else
rx += 1;
break;
case 1: //아래로 움직이는 방향. 열이 같음
if (cur.rx < cur.bx) //처음에 빨간파란구슬 위치 비교
rx -= 1; //도착지점 비교
else
bx -= 1;
break;
case 2: //좌로 움직이는 방향. 행이 같음
if (cur.ry < cur.by) //처음에 빨간파란구슬 위치 비교
by += 1; //도착지점 비교
else
ry += 1;
break;
case 3: //우로 움직이는 방향. 행이 같음
if (cur.ry < cur.by) //처음에 빨간파란구슬 위치 비교
ry -= 1; //도착지점 비교
else
by -= 1;
break;
}
}

if (!v[rx][ry][bx][by]) { //벽을 만났을때 갈 수 있는 새로운 위치 큐에 넣어줌
queue.offer(new Point(rx, ry, bx, by, cur.cnt + 1));
}
}
}
System.out.println(-1); //다 돌았는데도 못나오면 -1
}


}
Loading