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
43 changes: 43 additions & 0 deletions .idea/workspace.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

116 changes: 116 additions & 0 deletions week5/KCW/W5_1194.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;

//1194 달이 차오른다, 가자.
/*
조건 1. 빈칸은 언제나 이동 가능, 벽은 절대 이동 불가능
조건 2. 열쇠가 있을 때만 문을 지날 수 있음
조건 3. 출구는 한 개가 아님
조건 4. 같은 열쇠나 문이 여러 번 나올 수 있음, 문에 대응하는 열쇠가 없을 수도 있음
조건 5. 열쇠는 여러 번 사용할 수 있음

사용 방법 : BFS -> 메모리초과
대안 : visited배열과 hasKey 배열을 비트마스킹 방법으로 표현 -> 메모리초과
대안 : hasKey 숫자가 여러 배리에이션으로 다양해졌으니 visited 배열을 전역변수로 두고 관리
-> 다음의 과정으로 풀 수 있었음
*/
public class Main {
static int n, m;
static int[] dx = {0, 0, -1, 1};
static int[] dy = {-1, 1, 0, 0};
static Character[][] map;
static boolean[][][] visited;

static class Stat {
int x, y, depth, hasKey;

Stat(int x, int y, int depth, int hasKey) {
this.x = x;
this.y = y;
this.depth = depth;
this.hasKey = hasKey;
}

boolean unlocked(char ch) {
return (hasKey & (1 << (ch - 'A'))) != 0; //0100가 반환된다면 이 값은 4임
}
}

static int bfs(int x, int y) {
Queue<Stat> q = new LinkedList<>();
boolean[][][] visited = new boolean[n][m][1 << 6]; //6은 열쇠 개수
q.add(new Stat(x, y, 1, 0));
visited[y][x][0] = true;

while (!q.isEmpty()) {
Stat p = q.poll();

for (int i = 0; i < 4; i++) {
int nx = p.x + dx[i];
int ny = p.y + dy[i];

// 경계 조건 & 벽이거나 & 방문한 적 있으면 continue
if (nx < 0 || ny < 0 || nx >= m || ny >= n || map[ny][nx] == '#' || visited[ny][nx][p.hasKey]) continue;

if (map[ny][nx] == '1') {
return p.depth;
}

// 열쇠를 줍는 경우
if (map[ny][nx] >= 'a' && map[ny][nx] <= 'f') {
int keyIdx = 1 << (map[ny][nx] - 'a');
//열쇠가 이미 있는 경우
if((p.hasKey & keyIdx) == keyIdx ){
visited[ny][nx][p.hasKey] = true;
q.add(new Stat(nx, ny, p.depth + 1, p.hasKey));
} else{ //열쇠를 처음 얻는 경우
int newHasKey = p.hasKey | keyIdx; // 복사본 생성
visited[ny][nx][newHasKey] = true;
visited[ny][nx][p.hasKey] = true;

q.add(new Stat(nx, ny, p.depth + 1, newHasKey));
}
}
// 문인 경우
if (map[ny][nx] >= 'A' && map[ny][nx] <= 'F' && p.unlocked(map[ny][nx])) {
visited[ny][nx][p.hasKey] = true;
q.add(new Stat(nx, ny, p.depth + 1, p.hasKey));
}

// 열쇠 없을 때 이동
if (map[ny][nx] == '.') {
visited[ny][nx][p.hasKey] = true;
q.add(new Stat(nx, ny, p.depth + 1, p.hasKey));
}
}
}

return -1;
}

public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
n = Integer.parseInt(st.nextToken());
m = Integer.parseInt(st.nextToken());
map = new Character[n][m];
int x = 0, y = 0;
for (int i = 0; i < n; i++) {
String str = br.readLine();
for (int j = 0; j < m; j++) {
map[i][j] = str.charAt(j);
if (str.charAt(j) == '0') {
x = j;
y = i;
map[i][j] = '.';
}
}
}

System.out.println(bfs(x, y));
}
}
36 changes: 36 additions & 0 deletions week5/KCW/W5_13458.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
//13458 시험 감독
public class Main {
static int N, B, C;
static int[] arr;

public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
N = Integer.parseInt(br.readLine());
arr = new int[N];
st = new StringTokenizer(br.readLine());
for (int i = 0; i < N; i++) {
arr[i] = Integer.parseInt(st.nextToken());
}
st = new StringTokenizer(br.readLine());
B = Integer.parseInt(st.nextToken());
C = Integer.parseInt(st.nextToken());

long cnt = 0;
for (int i = 0; i < N; i++) {
cnt += 1;
if (arr[i] <= B) {
continue;
}
double viewers = (double) (arr[i] - B) / C;
if ((viewers * 10) % 10 > 0)//올림을 위해 소수점 검사
cnt += 1;
cnt += (arr[i] - B) / C;
}
System.out.println(cnt);
}
}
135 changes: 135 additions & 0 deletions week5/KCW/W5_16236.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
//16236 아기상어
/*
fish 클래스
findFish 함수(int x, int y, int size)
먹는 기작은 다음과 같다.
1. find로 가장 가까운 fish를 찾는다.
2. 아기상어의 크기, x, y를 바꾸고 결과값을 저장한다
3. 1번부터 반복한다.

find 함수
1. 아기상어보다 큰 물고기는 벽이다. 지나갈 수 없다.
2. 자신의 크기와 같은 수의 물고기를 먹을 때 마다 크기가 1 증가한다.
3. 크기가 같은 물고기는 먹을 수 없지만, 그 물고기가 있는 칸은 지나갈 수 있다.
*/
public class Main {
static int n;
static int[][] map;

static class Fish implements Comparable<Fish> {
int x, y, size, depth;

Fish(int x, int y, int size, int depth) {
this.x = x;
this.y = y;
this.size = size;
this.depth = depth;
}

@Override
public int compareTo(Fish o) {
if (depth == o.depth) {
if (y == o.y) {
return x - o.x;
}
return y - o.y; //위에 있어야 함, 0과 2가 있을 때 0 - 2 음수 그대로
}
return depth - o.depth;//음수가 나오면 맞는 방향, 양수가 나오면 방향을 바꿔줌
}
}

static class LittleShark extends Fish {
int ateFish;
LittleShark(int x, int y, int size, int depth) {
super(x, y, size, depth);
ateFish = 0;
}

public void eat(Fish fish){
x = fish.x;
y = fish.y;
depth += fish.depth;
ateFish++;
if(ateFish == size) {
size++;
ateFish = 0;
}
map[y][x] = 0;
}
}

static Fish find(Fish littleShark) {
int[] dx = {0, 0, -1, 1};
int[] dy = {1, -1, 0, 0};
boolean[][] visited = new boolean[n][n];
int[][] fishMap = new int[n][n];
for (int i = 0; i < n; i++) {
fishMap[i] = map[i].clone(); // 깊은 복사
}
Queue<Fish> q = new LinkedList<>();
ArrayList<Fish> fishes = new ArrayList<>();

q.add(littleShark);
visited[littleShark.y][littleShark.x] = true;

while (!q.isEmpty()) {
Fish fish = q.poll();

for (int i = 0; i < 4; i++) {
int nx = fish.x + dx[i];
int ny = fish.y + dy[i];

if (nx < 0 || ny < 0 || nx >= n || ny >= n || visited[ny][nx]) continue;

if (fishMap[ny][nx] == 0 || fishMap[ny][nx] == littleShark.size) {
//물고기가 없거나 물고기가 아기상어와 같은 크기일 때 지나서 감
visited[ny][nx] = true;
q.add(new Fish(nx, ny, fish.size, fish.depth + 1));
} else if (fishMap[ny][nx] > littleShark.size) {
visited[ny][nx] = true;
//물고기가 아기상어보다 클 때 : 돌아서 감, 아무것도 큐에 넣지 않음
} else if (fishMap[ny][nx] < littleShark.size) {
//아기상어가 먹을 수 있는 물고기일 때 : 먹을 수 있는 후보에 들어감
visited[ny][nx] = true;
fishes.add(new Fish(nx, ny, fishMap[ny][nx], fish.depth + 1));
fishMap[ny][nx] = 0;
}
}
}

if (fishes.isEmpty()) return null;
Collections.sort(fishes);
return fishes.get(0);
}

public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
n = Integer.parseInt(br.readLine());
map = new int[n][n];
LittleShark littleShark = null;
for (int i = 0; i < n; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 0; j < n; j++) {
map[i][j] = Integer.parseInt(st.nextToken());
if (map[i][j] == 9) {
littleShark = new LittleShark(j, i, 2, 0);
map[i][j] = 0;
}
}
}

Fish foodFish = find(littleShark);
while (foodFish != null) {
littleShark.eat(foodFish);
Fish newLittleShark = new Fish(littleShark.x, littleShark.y, littleShark.size, 0);
foodFish = find(newLittleShark);
}

System.out.println(littleShark.depth);
}
}
Loading