Skip to content
52 changes: 52 additions & 0 deletions BOJ/1000-5000번/HW_1030.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import java.io.*;
import java.util.*;

// 프렉탈 평면이 단위 시간이 진행될 때 마다 크기가 증가함
// 프랙탈 한변 길이 : N^S
// 검정색 영역이 아닌 경우 색을 결정할 수 없음
// 현재 시간에서 해당 위치 어떤 색인지 결정 X
// 색을 결정하려면? 더 작은 블록(상위 패턴)의 좌표로 이동해서 재귀적으로 확인 해줘야함
public class HW_1030 {
static int S, N, K, R1, R2, C1, C2;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());

S = Integer.parseInt(st.nextToken()); // 시간
N = Integer.parseInt(st.nextToken()); // 분할 크기
K = Integer.parseInt(st.nextToken()); // 검정 영역 크기
R1 = Integer.parseInt(st.nextToken());
R2 = Integer.parseInt(st.nextToken());
C1 = Integer.parseInt(st.nextToken());
C2 = Integer.parseInt(st.nextToken());

int size = (int) Math.pow(N, S); // 프랙탈 한변 길이 : N^S

// 주어진 범위만 확인
for (int r = R1; r <= R2; r++) {
for (int c = C1; c <= C2; c++) {
System.out.print(isCheck(r, c, size)); // 각 좌표의 색 계산
}
System.out.println();
}
}

static int isCheck(int r, int c, int size) {
if (size == 1) { // 단위 시간 0일 때
return 0; // 흰색(0) 정사각형 한 개
}

int curSize = size / N; // 현재 블록 크기
int s = curSize * (N - K) / 2; // 검정 영역 시작
int e = curSize * (N + K) / 2; // 검정 영역 끝

// 현재 좌표가 검정 영역에 속하면 색을 바로 반환(1)
if (s <= r && r < e && s <= c && c < e) {
return 1;
}

// 검정 영역에 속하지 않으면
// 좌표를 상위 블록으로 변환하여 재귀적으로 확인
return isCheck(r % curSize, c % curSize, curSize);
}
}
34 changes: 34 additions & 0 deletions BOJ/1000-5000번/HW_1725.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@

import java.io.*;
import java.util.*;

// N<= 10^5 시간 복잡도 : O(N)
public class HW_1725 {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int N = Integer.parseInt(br.readLine());
int[] heights = new int[N+1];

for(int i=0; i<N; i++) {
heights[i] = Integer.parseInt(br.readLine());
}
System.out.println(simulation(heights));
}
static long simulation(int[] heights) {
Stack<Integer> stack = new Stack<>(); // 막대 높이를 저장
long max = 0; // 막대의 높이(10^9) * 너비(10^5) -> long

for(int i=0; i<heights.length; i++) { // 직사각형의 최대 높이 계산
while(!stack.isEmpty() && heights[i] < heights[stack.peek()]) { // 현재 높이가 스택의 최상단에 있는 높이보다 작으면
int h = heights[stack.pop()]; // 스택에서 높이를 꺼냄
int w = stack.isEmpty() ? i : i - stack.peek()-1;
// 스택이 비어있는 경우 -> 현재 인덱스(i)가 넓이 w=i;
// 스택이 비어있지X 경우 -> 왼쪽 경계(왼쪽에 남아있는 막대) w = i - stack.peek()-1;
// 현재 막대와의 간격만큼만 직사각형을 확장할 수 있기 때문
max = Math.max(max, (long)h*w);// 꺼낸 높이 기준으로 넓이 계산
}
stack.push(i);
}
return max;
}
}
48 changes: 48 additions & 0 deletions BOJ/1000-5000번/HW_1992.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

public class HW_1992 {
static int N;
static char[][] board;
static StringBuilder sb = new StringBuilder();
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

int N = Integer.parseInt(br.readLine());
board = new char[N][N];
for(int i=0; i<N; i++){
String line = br.readLine();
board[i] = line.toCharArray();
}
Quad(0, 0, N);
System.out.println(sb);
}
static void Quad(int x, int y, int size){
if(isValid(x, y, size)){
sb.append(board[x][y]);
return;
}
int half = size/2;

sb.append('(');
Quad(x, y, half); // 왼쪽 위
Quad(x, y+half, half);
Quad(x+half, y, half);
Quad(x+half, y+half, half);
sb.append(')');
}
static boolean isValid(int x, int y, int size){ // 압축 가능한지 확인
char value = board[x][y]; // 첫번째 값 기준
// 0 + 1 섞여있으면 4개 영역으로 나눠야함
for(int i=x; i<x+size; i++){
for(int j=y; j<y+size; j++){
if(value != board[i][j]){
return false; // 한 문자라도 다르면 false
}
}
}
return true; // 모두 같은 값일 경우 true
}
}
84 changes: 84 additions & 0 deletions BOJ/1000-5000번/HW_4803.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import java.io.*;
import java.util.*;

// 시간복잡도 : O(V+E)
public class HW_4803 {
static List<List<Integer>> graph;
static boolean[] visited;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int test = 1;

while(true){
StringTokenizer st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken());
int M = Integer.parseInt(st.nextToken());

if(N == 0 && M == 0) {
break;
}
graph = new ArrayList<>();
for(int i=0; i<=N; i++) {
graph.add(new ArrayList<>());
}

for(int i=0; i<M; i++) { // 간선 입력 받기
st = new StringTokenizer(br.readLine());
int u = Integer.parseInt(st.nextToken());
int v = Integer.parseInt(st.nextToken());
graph.get(u).add(v); // 양방향
graph.get(v).add(u);
}
visited = new boolean[N+1];
int cnt = 0;

for(int i=1; i<=N; i++) {
if(!visited[i]) {
if(isCheck(i, -1)) {
cnt++;
}
}
}

if(cnt==0) {
System.out.printf("Case %d: No trees.", test);
}
else if(cnt==1) {
System.out.printf("Case %d: There is one tree.", test);
}
else {
System.out.printf("Case %d: A forest of %d trees.", test, cnt);
}
System.out.println();
test++;
}
}
static boolean isCheck(int node, int parent) { // BFS를 통해 트리 연결 부분 확인
Queue<int[]> queue = new LinkedList<>(); // 큐 초기화
queue.add(new int[] {node, parent}); // {탐색 시작할 정점, node의 부모 정점}
visited[node] = true;
int nodeCnt = 0; // 연결 요소에서 방문한 정점 개수 cnt
int edgeCnt = 0; // 연결 요소에서 방문한 간선 개수 cnt

while(!queue.isEmpty()) {
int[] cur = queue.poll(); // 큐에서 현재 노드, 부모 노드를 가져옴
int curNode = cur[0]; // 현재 노드
int curParent = cur[1]; // 부모 노드

nodeCnt++; // 정점 개수++

for(int i=0; i<graph.get(curNode).size(); i++) { // 인접 노드 탐색
int neighbor = graph.get(curNode).get(i);
edgeCnt++; // 간선 cnt++

if(!visited[neighbor]) { // 방문하지 않은 노드를 큐에 추가하고
visited[neighbor] = true; // 방문 표시
queue.add(new int[] {neighbor, curNode});
} else if(neighbor != curParent) { // 사이클 발생(이미 방문한 노드가 부모 노드가 아니라면)
return false; // 트리X
}
}
}
return edgeCnt/2 == nodeCnt -1; // 양방향 간선 고려 endge/2, 트리의 간선 개수 조건 V-1
}
}
25 changes: 25 additions & 0 deletions BOJ/1000-5000번/HW_9372.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

// 주어지는 비행 스케줄은 항상 연결 그래프를 이룸 -> MST(최소 스패닝트리)
// 모든 국가를 연결하는데 필요한 최선 간선의 수 찾기
// 연결된 그래프에서 MST 간선수 : N-1개
public class HW_9372 {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
int T = Integer.parseInt(br.readLine());

for(int i=0; i<T; i++){
st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken()); // 국가의 수
int M = Integer.parseInt(st.nextToken()); // 비행기의 수
for(int j=0; j<M; j++){
br.readLine(); // 각 비행 경로 입력만 받음(a, b)
}
System.out.println(N-1);
}
}
}
88 changes: 88 additions & 0 deletions CodeTree/2019-2020년/HW_윷놀이_사기단.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import java.util.*;
import java.io.*;

// 미리 계산을 하여 주어진 이동 횟수에 나갈 말의 종류를 잘 조합하여 얻을 수 있는 점수의 최댓값
// 주어진 이동 칸 수를 이용해서 얻을 수 있는 점수의 최댓값을 출력
// 파란 칸에 도착 시 최대 이동 횟수 이동하기
public class HW_윷놀이_사기단 {
static int[] board = {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40,
13, 16, 19, 22, 24, 28, 27, 26, 25, 30, 35, 0}; // 32칸
static int[] horse = {0, 0, 0, 0}; // 말 4개
static int[][] move = new int[33][6]; // 말의 이동 경로 저장
static int max = 0;
static int[] input;
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
input = new int[10];

for(int i=0; i<10; i++){
input[i] = Integer.parseInt(st.nextToken());
}

simulation();
dfs(0, 0, horse);
System.out.println(max);
}
private static void simulation(){
// 윷놀이판 이동 경로 설정
for(int i=0; i<20; i++){ // 직선 경로 이동 처리
for(int j=1; j<=5; j++){ // 윷 놀이 1~5칸 이동 가능
move[i][j] = i+j;
}
}

// 파란칸 도착 시 이동 경로 설정
move[5] = new int[]{0, 21, 22, 23, 29, 30}; // 0~5칸 이동
move[10] = new int[]{0, 24, 25, 29, 30, 31};
move[15] = new int[]{0, 26, 27, 28, 29, 30};

// 직선 경로 제외 이동 경로 설정
move[21] = new int[]{0, 22, 23, 29, 30, 31}; // 13~
move[22] = new int[]{0, 23, 29, 30, 31, 20};
move[23] = new int[]{0, 29, 30, 31, 20, 32}; // ~19

move[24] = new int[]{0, 25, 29, 30, 31, 20};
move[25] = new int[]{0, 29, 30, 31, 20, 32};
move[26] = new int[]{0, 27, 28, 29, 30, 31};
move[27] = new int[]{0, 28, 29, 30, 31, 20};
move[28] = new int[]{0, 29, 30, 31, 20, 32};
move[29] = new int[]{0, 30, 31, 20, 32, 32};
move[30] = new int[]{0, 31, 20, 32, 32, 32};
move[31] = new int[]{0, 20, 32, 32, 32, 32};

// 도착 지점 경로 설정
move[16][5] = 32;
move[17] = new int[]{0, 18, 19, 20, 32, 32};
move[18] = new int[]{0, 19, 20, 32, 32, 32};
move[19] = new int[]{0, 20, 32, 32, 32, 32};
move[20] = new int[]{0, 32, 32, 32, 32, 32};
}
static void dfs(int moveCnt, int score, int[] horse){
if(moveCnt==10){ // 10번 이동 완료 시
max = Math.max(max, score);
return;
}
for(int i=0; i<4; i++){
int cur = horse[i];
if(cur==32){ // 도착하면 움직이지않음
continue;
}
int next = move[cur][input[moveCnt]]; // 다음 위치 계산
boolean flag = true;
for(int j=0; j<4; j++){ // 겹치지 않아야함
if(i!=j && horse[j]==next && next !=32){ // 도착시 움직이지 않음
flag = false;
break;
}
}
if(!flag){
continue;
}
horse[i] = next; // 말 이동
dfs(moveCnt+1, score+board[next], horse);
horse[i] = cur; // 상태 복원?
}

}
}
Loading