Skip to content

Commit

Permalink
240114
Browse files Browse the repository at this point in the history
  • Loading branch information
NavyHubb committed Jan 14, 2024
1 parent 897ad9c commit 15673a8
Show file tree
Hide file tree
Showing 3 changed files with 295 additions and 0 deletions.
86 changes: 86 additions & 0 deletions src/dp/BOJ_1943_동전분배.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package dp;

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

/**
* [문제 분석]
* 세 개의 케이스가 주어진다
* 동전의 크기와 갯수가 주어질 때, 전체 금액을 절반으로 나눌 수 있는지 판단하라
*
* [문제 풀이]
*
*/
public class BOJ_1943_동전분배 {

static int N, total;
static Coin[] coins;
static boolean[] dp;
static class Coin {
int value, quantity;

public Coin(int value, int quantity) {
this.value = value;
this.quantity = quantity;
}
}

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

for (int t = 0; t < 3; t++) {
N = Integer.parseInt(br.readLine());
coins = new Coin[N];
total = 0;
dp = new boolean[100_001]; // 원장님이 주신 금액의 최댓값은 100,000원

for (int i = 0; i < N; i++) {
st = new StringTokenizer(br.readLine());
int value = Integer.parseInt(st.nextToken());
int quantity = Integer.parseInt(st.nextToken());

coins[i] = new Coin(value, quantity);
total += value * quantity;

// 현재 동전으로 만들 수 있는 금액을 true 처리
for (int j = 1; j <= quantity; j++) {
dp[value * j] = true;
}
}

if (solution()) {
System.out.println(1);
} else {
System.out.println(0);
}
}
}

private static boolean solution() {
if (total%2 != 0) {
return false; // 총액이 홀수인 경우
}
if (dp[total/2]) { // 이미 반으로 나눌 수 있음이 확인된 경우
return true;
}

dp[0] = true;
for (Coin coin : coins) {
for (int i = total/2; i >= coin.value; i--) {
if (dp[i - coin.value]) {
for (int j = 1; j <= coin.quantity; j++) {
if ((i - coin.value) + (coin.value*j) > total/2) break; // total/2 이상으로는 탐색할 필요 없음

dp[(i - coin.value) + (coin.value*j)] = true;
}
}
}
}

return dp[total/2];
}

}
138 changes: 138 additions & 0 deletions src/graph/BOJ_5427_불.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
package graph;

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

/**
* [문제 분석]
* 건물의 일부에 불이 났고, 상근이는 출구를 향해 뛰고 있다
* 매 초마다 불은 인접사방의 빈 공간으로 확산된다
* 상근이는 벽을 통과할 수 없고, 불이 있는 칸, 이제 불이 있을 칸으로 이동할 수 없다
* 얼마나 빨리 빌딩을 탈출할 수 있는지 구하라
*
* [문제 풀이]
*
*/
public class BOJ_5427_불 {

static int N, M;
static char[][] map;
static int[] di = {-1, 1, 0, 0};
static int[] dj = {0, 0, -1, 1};
static Queue<Point> fires;
static Queue<Person> people;
static class Point {
int i, j;

public Point(int i, int j) {
this.i = i;
this.j = j;
}
}
static class Person {
int i, j, cnt;

public Person(int i, int j, int cnt) {
this.i = i;
this.j = j;
this.cnt = cnt;
}
}

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

int T = Integer.parseInt(br.readLine());
while (T-- > 0) {
st = new StringTokenizer(br.readLine());
M = Integer.parseInt(st.nextToken());
N = Integer.parseInt(st.nextToken());
fires = new LinkedList<>();
people = new LinkedList<>();

map = new char[N][M];
for (int i = 0; i < N; i++) {
String str = br.readLine();
for (int j = 0; j < M; j++) {
char ch = str.charAt(j);
if (ch == '@') { // 상근
people.add(new Person(i, j, 0));
} else if (ch == '*') { // 불
fires.add(new Point(i, j));
}
map[i][j] = ch;
}
}

solution();
}
}

private static void solution() {
int result = -1;
while (true) {
// 불 확산
spread();

// 상근 이동
result = move();
if (result != -1) break;
if (people.isEmpty()) break;
}

if (result != -1) {
System.out.println(result);
} else {
System.out.println("IMPOSSIBLE");
}
}

private static int move() {
int size = people.size();
for (int i = 0; i < size; i++) {
Person cur = people.poll();

for (int d = 0; d < 4; d++) {
int ni = cur.i + di[d];
int nj = cur.j + dj[d];

if (ni < 0 || nj < 0 || ni >= N || nj >= M) {
return cur.cnt + 1;
}

if (map[ni][nj] == '.') {
map[ni][nj] = '@';
people.add(new Person(ni, nj, cur.cnt+1));
}
}
}

return -1;
}

private static void spread() {
// 현재 저장되어 있는 불의 위치만큼만 수행
int size = fires.size();
for (int i = 0; i < size; i++) {
Point point = fires.poll();

for (int d = 0; d < 4; d++) {
int ni = point.i + di[d];
int nj = point.j + dj[d];

if (ni < 0 || nj < 0 || ni >= N || nj >= M) continue;

if (map[ni][nj] == '.' || map[ni][nj] == '@') {
map[ni][nj] = '*';
fires.add(new Point(ni, nj));
}
}
}
}

}
71 changes: 71 additions & 0 deletions src/greedy/BOJ_2138_전구와스위치.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package greedy;

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

public class BOJ_2138_전구와스위치 {

static final int INF = Integer.MAX_VALUE;
static int N;
static boolean[] now_on, goal, now_off;

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

N = Integer.parseInt(br.readLine());
String str1 = br.readLine();
String str2 = br.readLine();

now_on = new boolean[N];
now_off = new boolean[N];
goal = new boolean[N];

int cnt_on = 1, cnt_off = 0; // 스위치를 켜는 경우의 누른 횟수와 끄는 경우의 누른 횟수

for (int i = 0; i < N; i++) {
now_on[i] = str1.charAt(i) == '1' ? true : false;
now_off[i] = now_on[i];
goal[i] = str2.charAt(i) == '1' ? true : false;
}

// 첫번째 스위치를 켜는 경우: 첫번째 전구와 두번째 전구가 상태가 바뀐다
now_on[0] = !now_on[0];
now_on[1] = !now_on[1];

// 두번째 스위치부터 탐색
for (int i = 1; i < N; i++) {
if (now_on[i-1] != goal[i-1]) { // 현재 스위치의 위치의 좌측 전구의 상태가 목표 상태와 다르다면
// 현재 스위치 on
now_on[i-1] = !now_on[i-1];
now_on[i] = !now_on[i];
if (i < N-1) { // 마지막 스위치가 아닌 경우에만 i+1 전구에 접근. ArrayOutOfIndex 방지
now_on[i+1] = !now_on[i+1];
}

cnt_on++;
}

if (now_off[i-1] != goal[i-1]) { // 현재 스위치의 위치의 좌측 전구의 상태가 목표 상태와 다르다면
// 현재 스위치 on
now_off[i-1] = !now_off[i-1];
now_off[i] = !now_off[i];
if (i < N-1) { // 마지막 스위치가 아닌 경우에만 i+1 전구에 접근. ArrayOutOfIndex 방지
now_off[i+1] = !now_off[i+1];
}

cnt_off++;
}
}

if (now_on[N-1] != goal[N-1]) cnt_on = INF;
if (now_off[N-1] != goal[N-1]) cnt_off = INF;

if (cnt_on == INF && cnt_off == INF) {
System.out.println(-1);
} else {
System.out.println(Math.min(cnt_on, cnt_off));
}
}

}

0 comments on commit 15673a8

Please sign in to comment.