📙 Algorithm Solving/Java
📙[Algo] 24.03.25 알고리즘
혜덕hyeduck
2024. 3. 26. 12:29
알고리즘 문제) BOJ 2644. 촌수계산
문제 요약
- 두 사람의 촌수 계산하기
시간 제한
- 2초
입력
- 1,2,3,…n의 연속된 번호로 각각 표시 된다.
- 첫쨰 줄 : 전체 사람의 수 n
- 둘째 줄 : 천수를 게산해야하는 서로 다른 두 사람의 번호
- 셋째 줄 : 부모 자식들 간의 관계 개수 m
- 넷째줄 부터 부모 자식간의 관계를 나타내는 번호 x, y
- x는 y의 부모 번호
출력
- 두 사람의 촌수 출력
- 없다면 -1
코드
import java.io.*;
import java.util.StringTokenizer;
public class Main {
static int N;
static int targetA, targetB;
static int M;
static boolean[] visited;
static int[][] arr;
static int answer = -1;
static void dfs(int node, int cnt) {
if (node == targetB) {
answer = cnt;
return;
}
visited[node] = true;
for (int i = 1; i <= N; i++) {
if (!visited[i] && arr[node][i] == 1) {
dfs(i, cnt + 1);
}
}
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringTokenizer st;
N = Integer.parseInt(br.readLine());
st = new StringTokenizer(br.readLine());
targetA = Integer.parseInt(st.nextToken());
targetB = Integer.parseInt(st.nextToken());
M = Integer.parseInt(br.readLine());
arr = new int[N + 1][N + 1];
int from, to;
for (int i = 0; i < M; i++) {
st = new StringTokenizer(br.readLine());
from = Integer.parseInt(st.nextToken());
to = Integer.parseInt(st.nextToken());
arr[from][to] = 1;
arr[to][from] = 1;
}
visited = new boolean[N + 1];
dfs(targetA, 0);
bw.write(String.valueOf(answer));
bw.flush();
bw.close();
br.close();
}
}
알고리즘 문제) BOJ 3109. 빵집
문제 요약
- R*C격자의 지도가 주어짐
- 첫째 열은 근처 빵집의 가스관, 마지막 열은 원웅이의 빵집
- 가스관과 원웅이의 빵집을 연결하는 파이파를 설치하려고 함
- 이때 건물이 있는 경우에는 파이프를 놓을 수 없음
- 모든 파이프는 첫째열에서 시작
- 오른쪽, 오른쪽위대각선, 오른쪽아래대각선 연결 가능
- 이떄 경로는 겹치면 안 됨(각 칸을 지나는 파이프는 하나)
- 설치가능한 파이프라인의 최대 개수?
시간 제한
- 1초
입력
- R C
- 1≤R≤1만
- 5≤C≤500
- R개의 줄에 지도가 주어짐
- . : 빈칸, x : 건물
출력
- 놓을 수 있는 파이프라인의 최대 개수를 출력
접근법
가장 위로가는 것을 우선으로 하면서 dfs
visited 처리 주의….
코드
import java.io.*;
import java.util.StringTokenizer;
public class Main {
static int R, C;
static char[][] map;
// 우상 우 우하
static int[] delR = {-1, 0, 1};
static int[] delC = {1, 1, 1};
static boolean[][] visited;
static int cnt;
static boolean check(int row, int col) {
return 0 <= row && 0 <= col && row < R && col < C
&& !visited[row][col] && map[row][col] == '.';
}
static boolean dfs(int row, int col) {
if (col == C - 1) return true;
int mrow, mcol;
boolean ret;
for (int i = 0; i < 3; i++) {
mrow = row + delR[i];
mcol = col + delC[i];
if (!check(mrow, mcol)) continue;
visited[mrow][mcol] = true;
ret = dfs(mrow, mcol);
if (ret) return ret;
// visited[mrow][mcol] = false;
}
return false;
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringTokenizer st;
st = new StringTokenizer(br.readLine());
R = Integer.parseInt(st.nextToken());
C = Integer.parseInt(st.nextToken());
map = new char[R][C];
String input;
for (int i = 0; i < R; i++) {
input = br.readLine();
for (int j = 0; j < C; j++) {
map[i][j] = input.charAt(j);
}
}
visited = new boolean[R][C];
for (int i = 0; i < R; i++) {
if (dfs(i, 0)) cnt++;
}
bw.write(String.valueOf(cnt));
bw.flush();
bw.close();
br.close();
}
}
알고리즘 문제) BOJ 14247. 나무 자르기
문제 요약
- N개의 나무가 있고, 하루에 하나씩 N일 산에 오르면 나무를 자름
- 나무의 처음 길이와 하루에 자라는 양이 주어졌을 때, 영선이가 얻을 수 있는 최대 나무양을 구하시오
시간 제한
- 2초
입력
- 나무 개수 N
- 1≤N≤10만
- 첫날 올라갔을 때 나무의 길이들이 N개 주어짐
- 1≤Hi≤10만
- 그 다음 줄에는 나무들이 하루에 자라는 길이 N개가 주어짐
- 1≤Ai≤1만
출력
- 나무를 잘라서 구할 수 있는 최대 양?
접근법
N이 10만 개이므로 for문은 1개만 사용 가능
1일차 | 2일차 | 3일차 | 4일차 | 5일차 |
1(2) | 3 | 5 | 7 | 9 |
3(7) | 10 | 17 | 24 | 31 |
2(3) | 5 | 8 | 11 | 14 |
4(4) | 8 | 12 | 16 | 4 |
6(1) | 7 | 8 | 9 | 10 |
1일차 | 2일차 | 3일차 | 4일차 | 5일차 |
1(2) | 3 | 5 | 7 | 9 |
3(7) | 10 | 17 | 24 | 31 |
2(3) | 5 | 8 | 11 | 14 |
4(4) | 8 | 12 | 16 | 4 |
100(2) | 102 | 104 | 106 | 108 |
결국 나무를 자를 때 매일 성장하는 속도가 얼마나 되는지가 중요 ⇒ 같은 나무를 여러번 잘라도 최종적으로 얻을 수 있는 개수는 일정
그렇기 떄문에 자라는 속도가 느린 순서대로 잘라간다. ⇒ 자라는 속도만큼 내가 추가적으로 얻을 수 있는 양이라고 생각!
코드
import java.io.*;
import java.util.Arrays;
import java.util.StringTokenizer;
public class Main {
static class Tree **implements Comparable<Tree>** {
int idx;
int grow;
public Tree(int idx, int grow) {
this.idx = idx;
this.grow = grow;
}
@Override
**public int compareTo(Tree o)** {
if(**this.grow == o.grow**) return this.idx - o.idx;
else return **this.grow - o.grow**;
}
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringTokenizer st;
int N = Integer.parseInt(br.readLine());
int[] trees = new int[N];
st = new StringTokenizer(br.readLine());
for (int i = 0; i < N; i++) {
trees[i] = Integer.parseInt(st.nextToken());
}
Tree[] growUp = new Tree[N];
st = new StringTokenizer(br.readLine());
for (int i = 0; i < N; i++) {
growUp[i] = new Tree(i, Integer.parseInt(st.nextToken()));
}
Arrays.sort(growUp);
long sum = 0;
for (int i = 0; i < N; i++) {
sum += (trees[growUp[i].idx] + (long) i * growUp[i].grow);
}
bw.write(String.valueOf(sum));
bw.flush();
bw.close();
br.close();
}
}