Skip to content

[허승연] 백준 8월 4주차 숙제 (9/7/화) #107

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Sep 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 108 additions & 0 deletions syheo/baekjoon_java/Main_17090.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package syheo.baekjoon_java;

import java.awt.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;

/**
* 백준
* solved.ac
* 17090
* 미로 탈출하기
* 골드 2
* 아이디어 :
* 방문하지 않은 노드에 ��해서 dfs를 돈다.
* dfs에서 탈출조건은
* 1. 범위 밖으로 이탈했을 경우
* 2. dp[row][col] 이 0보다 클 경우 ( 이전에 탈출 경로를 지나친 경우 )
* 그외에 싸이클을 발견했을 경우 즉, 방문했던 노드를 또 지나는 경우에
* 해당 경로의 방문처리를 취소한다.
* */

//U인 경우에는 (r-1, c)로 이동해야 한다.
//R인 경우에는 (r, c+1)로 이동해야 한다.
//D인 경우에는 (r+1, c)로 이동해야 한다.
//L인 경우에는 (r, c-1)로 이동해야 한다.

public class Main_17090 {

static BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
static StringTokenizer tokens;
static int N,M;
static String inputStr;
static char[][] maps;
static boolean[][] visited;
static int[][] dp;
static int cnt = 0;
static Queue<Point> queue = new LinkedList<>();

public static void main(String[] args) throws IOException {
// 1. input
tokens = new StringTokenizer(input.readLine());
N = Integer.parseInt(tokens.nextToken());
M = Integer.parseInt(tokens.nextToken());
maps = new char[N][M];

for (int i = 0; i < N; i++) {
inputStr = input.readLine();
for (int j = 0; j < M; j++) {
maps[i][j] = inputStr.charAt(j);
}
}

visited = new boolean[N][M];
dp = new int[N][M];

// 2. bfs
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
if(!visited[i][j]){
cnt+=dfs(i,j,0);
}
}
}

// 3. print cnt
System.out.println(cnt);
}

private static int dfs(int row, int col,int cnt) {
// 탈출 체크
if((row<0 || row>=N) || (col<0 || col>=M) || dp[row][col] >0){
return cnt;
}
// 방문한델 또 방문? -> 싸이클
if(visited[row][col]){
return 0;
}
// 방문 처리
else{
visited[row][col] = true;
}
// 방향에 따라 방문
if(maps[row][col]=='U'){
cnt=dfs(row-1,col,cnt+1);
}
if(maps[row][col]=='D'){
cnt=dfs(row+1,col,cnt+1);
}
if(maps[row][col]=='R'){
cnt=dfs(row,col+1,cnt+1);
}
if(maps[row][col]=='L'){
cnt=dfs(row,col-1,cnt+1);
}
if(cnt == 0)
visited[row][col] = false;
else
dp[row][col] += cnt;



return cnt;
}
}
150 changes: 150 additions & 0 deletions syheo/baekjoon_java/Main_2931.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
package syheo.baekjoon_java;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
import java.util.stream.Collectors;

/**
* 백준
* solved.ac
* 2931
* 가스관
* 골드 3
* 구현
* 아이디��� : 진짜 쌉구현 문제..
* 일단 아이디어는 '.'인 곳 중 상하좌우에 1~7 에 해당하는 파이프가 directionMap 을 통해 연결되어 있는 상태로 존재하는지 확인함.
* 만약 위 경우가 있을 경우 어떤 파이프를 둬야 하는지 확인후 출력 후 종료.
* */

public class Main_2931 {

static Map<Integer,List<Integer>> pipes;
// 1-하,우 2-상,우 3-좌,상 4-좌,하 5-상,하 6-좌,우 7-상,하,좌,우, 8-m, 9-z
static Map<Integer, List<Integer>> directionMap;
static int[] dx = {-1,0,1,0};
static int[] dy = {0,1,0,-1};
static BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
static StringTokenizer tokens;
static int R, C;
static int[][] maps;
static List<Integer> result = new ArrayList<>();

public static void main(String[] args) throws IOException {

// 1. input
tokens = new StringTokenizer(input.readLine());

R = Integer.parseInt(tokens.nextToken());
C = Integer.parseInt(tokens.nextToken());

maps = new int[R][C];
for (int i = 0; i < R; i++) {
String nowRow = input.readLine();
for (int j = 0; j < C; j++) {
if (nowRow.charAt(j) == '|') {
maps[i][j] = 5;
} else if (nowRow.charAt(j) == '-') {
maps[i][j] = 6;
} else if (nowRow.charAt(j) == '+') {
maps[i][j] = 7;
} else if (nowRow.charAt(j) == 'M') {
maps[i][j] = 8;
} else if (nowRow.charAt(j) == 'Z') {
maps[i][j] = 9;
} else if (nowRow.charAt(j) == '.') {
maps[i][j] = 0;
} else {
maps[i][j] = nowRow.charAt(j) - '0';
}
} // for
} // for

// 2-1. set directionMap
directionMap = new HashMap<>();
directionMap.put(0, Arrays.stream(new int[]{1, 4, 5, 7})
.boxed()
.collect(Collectors.toList()));
directionMap.put(1, Arrays.stream(new int[]{3,4,6,7})
.boxed()
.collect(Collectors.toList()));
directionMap.put(2, Arrays.stream(new int[]{2, 3, 5, 7})
.boxed()
.collect(Collectors.toList()));
directionMap.put(3, Arrays.stream(new int[]{1, 2,6, 7})
.boxed()
.collect(Collectors.toList()));

// 2-2. set pipes
pipes = new HashMap<>();

pipes.put(1, Arrays.stream(new int[]{1,2})
.boxed()
.collect(Collectors.toList()));
pipes.put(2, Arrays.stream(new int[]{0,1})
.boxed()
.collect(Collectors.toList()));
pipes.put(3, Arrays.stream(new int[]{0,3})
.boxed()
.collect(Collectors.toList()));
pipes.put(4, Arrays.stream(new int[]{2,3})
.boxed()
.collect(Collectors.toList()));
pipes.put(5, Arrays.stream(new int[]{0,2})
.boxed()
.collect(Collectors.toList()));
pipes.put(6, Arrays.stream(new int[]{1,3})
.boxed()
.collect(Collectors.toList()));
pipes.put(7, Arrays.stream(new int[]{0,1,2,3})
.boxed()
.collect(Collectors.toList()));

// 3. find
for (int i = 0; i < R; i++) {
for (int j = 0; j < C; j++) {
if (maps[i][j]==0){
result = new ArrayList<>();
// 상하좌우 탐색
for (int k = 0; k < 4; k++) {
int row = i+dx[k];
int col = j+dy[k];
if(0<=row && row<R && 0<=col && col<C){
// 열려있는 파이프 구멍이 있나?
if(directionMap.get(k).contains(maps[row][col])){
result.add(k);
}
}
}
// 정답일 경우
if(!result.isEmpty()){
// 어떤 파이프인지 고름
for (int k = 1; k <= 7; k++) {
if(result.equals(pipes.get(k))){
char answer='0';
if(k<=4){
answer = Integer.toString(k).charAt(0);
}
else{
if(k==5){
answer = '|';
}
if(k==6){
answer = '-';
}
if(k==7){
answer = '+';
}
}
System.out.println((i+1)+" "+(j+1)+" "+answer);
return ;
}
}
}
}
}
}

}
}
102 changes: 102 additions & 0 deletions syheo/baekjoon_java/Main_5547.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package syheo.baekjoon_java;

import java.awt.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;

/**
* 백준
* solved.ac
* 5547
* 일루미네이션
* 실버1
* BFS
* 아이디어 :
* 처음엔 빌딩을 기준으로 bfs를 돌려서 감싸져 있는 빈 공간에 대한 처리를 하려다가
* 빈 공간이 1개일 경우만 고려해서 실패
* 다음 아이디어 :
* 테두리를 모두 0 으로 초기화 시키고 0,0 위치에서 bfs 를 실행하여
* 빌딩을 만나면 cnt 를 1 증가시켜서 답을 구함.
*/

public class Main_5547 {

static BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
static StringTokenizer tokens;
static int W,H;
static int cnt = 0;
static int[] dx = {-1,-1,0,1,1,0,-1,-1,0,1,1,0}; //row 기준 0~5 홀수 일 떄 , 6~11 짝수 일 때
static int[] dy = {0,1,1,1,0,-1,-1,0,1,0,-1,-1};
static int[][] maps;
static boolean[][] visited;
static int[][] dp;
static Queue<Point> queue = new LinkedList<>();

public static void main(String[] args) throws IOException {
// 1. input
tokens = new StringTokenizer(input.readLine());

W = Integer.parseInt(tokens.nextToken());
H = Integer.parseInt(tokens.nextToken());

maps = new int[H+2][W+2];
for (int j = 0; j <= W+1; j++) {
maps[0][j] = 0;
}
for (int i = 1; i <= H; i++) {
tokens = new StringTokenizer(input.readLine());
maps[i][0]=0;
for (int j = 1; j <= W; j++) {
maps[i][j] = Integer.parseInt(tokens.nextToken());
}
maps[i][W+1]=0;
}
for (int j = 0; j <= W+1; j++) {
maps[H+1][j] = 0;
}

dp = new int[H+2][W+2];
visited = new boolean[H+2][W+2];
// 2. calculate sum of light by bfS
//
bfs(0,0);


// 3. print
System.out.println(cnt);

}

private static void bfs(int i, int j) {
Point p;
int plus = 0;
queue.add(new Point(i,j));
visited[i][j]=true;
while(!queue.isEmpty()){
p = queue.poll();
if (p.x % 2 == 0) {
plus = 6;
}
else{
plus = 0;
}
for (int k = plus; k < plus+6; k++) {
if(p.x+dx[k]>=0 && p.x+dx[k]<=H+1 && p.y+dy[k]>=0 && p.y+dy[k]<=W+1 && !visited[p.x+dx[k]][p.y+dy[k]]){
// 빈 ��간이면 queue에 넣어줌
if(maps[p.x+dx[k]][p.y+dy[k]]==0){
queue.add(new Point(p.x+dx[k],p.y+dy[k]));
visited[p.x+dx[k]][p.y+dy[k]] = true;
}
// 건물을 만나면 카운팅
if(maps[p.x+dx[k]][p.y+dy[k]]==1){
cnt+=1;
}
}
}
}
}
}