diff --git a/week10/Baekjoon11055.java b/week10/Baekjoon11055.java index 150a6ca..90430e4 100644 --- a/week10/Baekjoon11055.java +++ b/week10/Baekjoon11055.java @@ -1,7 +1,65 @@ +import java.io.*; +import java.util.*; -public class Main { - - public static void main(String[] args) { - +/* + * 메모리: 11,844KB + * 시간: 84ms + */ +public class Baekjoon11055 { + // Input Handler + static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + static StringBuilder sb = new StringBuilder(); + static StringTokenizer st; + // types + // constants + // variables + static int N; + static int[] A = new int[1_000]; + static int len; + static int[] buffer = new int[1_000]; + static int[] dp = new int[1_000]; // A[i]를 마지막 원소로 하는 LIS의 원소 합 + + + static int lowerBound(int lo, int hi, int key) { + while(lo < hi) { + int mid = (lo + hi) >> 1; + if(A[buffer[mid]] < key) lo = mid + 1; + else hi = mid; + } + return lo; + } + + static int solution() { + int max = 0; + for(int i = 0; i < N; ++i) { + int at = lowerBound(0, len, A[i]); + if(at == len) ++len; + buffer[at] = i; + if(at == 0) dp[i] = A[i]; + else { + for(int j = 0; j < i; ++j) { + if(A[j] < A[i]) dp[i] = Math.max(dp[i], dp[j] + A[i]); + } + } + max = Math.max(max, dp[i]); + } + return max; + } + + public static void main(String[] args) throws IOException { + N = readInt(); + for(int i = 0; i < N; ++i) A[i] = readInt(); + System.out.print(solution()); + } + + static int readInt() throws IOException { + int c, n = System.in.read() & 0x0F, s = 1; + if(n == ('-' & 0x0F)) { + s = -1; + n = 0; + } + while((c = System.in.read()) >= 0x30) n = (n << 3) + (n << 1) + (c & 0x0F); + if(c == '\r') System.in.read(); + return n*s; } -} +} \ No newline at end of file diff --git a/week10/Baekjoon11657.java b/week10/Baekjoon11657.java index ee7e1ab..bfb922a 100644 --- a/week10/Baekjoon11657.java +++ b/week10/Baekjoon11657.java @@ -1,125 +1,66 @@ +import java.io.*; +import java.util.*; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.StringTokenizer; - -/** - * - * 각 지점을 중심으로 dfs 아래, 왼쪽, 오른쪽 방향으로만 dfs 탐색 depth:4로 - * - 탐색 시 최대값을 발견한다면 갱신 - * 탐색한 지점은 방문 처리 - * - * - * - * 가운데 모양은 따로 탐색 필요 - * - * - * @author SSAFY - * +/* + * 메모리: 12,528KB + * 시간: 104ms */ -public class Main_B_14500_테트로미노_연민호 { - - //하좌우상 - final static int[] dr = {1, 0, 0, -1}; - final static int[] dc = {0, -1, 1, 0}; - - - - static int N; //세로 크기 - static int M; //가로 크기 - - static int[][] map; //숫자판 정보 - - static boolean[][] visited; //방문체크 +public class Baekjoon11657 { + // Input Handler + static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + static StringBuilder sb = new StringBuilder(); + static StringTokenizer st; + // types + static class Edge{ + int s, e, w; + public Edge(int s, int e, int w) { this.s = s; this.e = e; this.w = w; } + } + // constants + // variables + static int N, M; + static Edge[] edges = new Edge[6_000]; + static long[] distances = new long[501]; - static int max; //최댓값 - 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 int[N+2][M+2]; - for(int i=1; i<=N; i++) { - st = new StringTokenizer(br.readLine()); - for(int j=1; j<=M; j++) { - map[i][j] = Integer.parseInt(st.nextToken()); + static boolean bellmanFord(int s) { + distances[s] = 0; + for(int i = 0; i < N; ++i) { + for(int j = 0; j < M; ++j) { + Edge edge = edges[j]; + if(distances[edge.s] != Integer.MAX_VALUE && distances[edge.e] > distances[edge.s] + edge.w) { + distances[edge.e] = distances[edge.s] + edge.w; + if(i == N - 1) return true; + } } } - - - visited = new boolean[N+2][M+2]; - - - for(int i=1; i<=N; i++) { - for(int j=1; j<=M; j++) { - visited[i][j] = true; - dfs(i,j, map[i][j], 1); - visited[i][j] = false; - - //가운데 블록 기준 3개 블록이 붙어있는 테트로미노 탐색 - etc(i, j, map[i][j]); - } - } - - System.out.println(max); + return false; } - - //가운데 블록 기준 3개 블록이 붙어있는 테트로미노 탐색 - private static void etc(int r, int c, int sum) { - - //(r,c) 기준 4방의 값을 모두 더함 - for(int d=0; d<4; d++) { - int nr = r+dr[d]; - int nc = c+dc[d]; - sum+= map[nr][nc]; + + public static void main(String[] args) throws IOException { + N = readInt(); M = readInt(); + Arrays.fill(distances, 1 , N + 1, Integer.MAX_VALUE); + for(int i = 0; i < M; ++i) { + edges[i] = new Edge(readInt(), readInt(), readInt()); } - //4방의 값을 하나씩 빼보면서 해당 값이 최댓값이라면 갱신 - for(int d=0; d<4; d++) { - int nr = r+dr[d]; - int nc = c+dc[d]; - max = Math.max(max, sum-map[nr][nc]); + if(bellmanFord(1)) System.out.println("-1"); + else { + for(int i = 2; i <= N; ++i) { + sb.append(distances[i] == Integer.MAX_VALUE ? -1 : distances[i]) + .append("\n"); + } + System.out.println(sb); } } - - /** - * 블록하나를 선택하고 다음 블록 선택은 재귀호출로 넘김 - * @param r - * @param c - * @param sum //선택한 블록의 숫자 합 - * @param cnt //선택한 블록의 개수 - */ - private static void dfs(int r, int c, int sum, int cnt) { - - //step01. 4개의 블록 선택 완료 - if(cnt==4) { - //step 02. 선택한 블록 숫자의 합이 최댓값이라면 갱신 - max = Math.max(sum, max); - return; - } - - //윗 방향을 제외한 3방향으로 이동하며 블록 선택 - for(int d=0; d<3; d++) { - - int nr = r+dr[d]; - int nc = c+dc[d]; - - //경계를 벗어나거나 이미 방문했다면 다음 방향 - if(nr>N || nc<1 || nc>M || visited[nr][nc]) continue; - - visited[nr][nc] = true; - dfs(nr, nc, sum+map[nr][nc], cnt+1); - visited[nr][nc] = false; + + static int readInt() throws IOException { + int c, n = System.in.read() & 0x0F, s = 1; + if(n == ('-' & 0x0F)) { + s = -1; + n = 0; } - + while((c = System.in.read()) >= 0x30) n = (n << 3) + (n << 1) + (c & 0x0F); + if(c == '\r') System.in.read(); + return n*s; } - - - -} +} \ No newline at end of file diff --git a/week10/Baekjoon1238.java b/week10/Baekjoon1238.java index ee7e1ab..2a2a8c2 100644 --- a/week10/Baekjoon1238.java +++ b/week10/Baekjoon1238.java @@ -1,125 +1,92 @@ +import java.io.*; +import java.util.*; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.StringTokenizer; - -/** - * - * 각 지점을 중심으로 dfs 아래, 왼쪽, 오른쪽 방향으로만 dfs 탐색 depth:4로 - * - 탐색 시 최대값을 발견한다면 갱신 - * 탐색한 지점은 방문 처리 - * - * - * - * 가운데 모양은 따로 탐색 필요 - * - * - * @author SSAFY - * +/* + * 메모리: 17,288KB + * 시간: 148ms */ -public class Main_B_14500_테트로미노_연민호 { - - //하좌우상 - final static int[] dr = {1, 0, 0, -1}; - final static int[] dc = {0, -1, 1, 0}; - - - - static int N; //세로 크기 - static int M; //가로 크기 +public class Baekjoon1238 { + static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + static StringBuilder sb = new StringBuilder(); + static StringTokenizer st = null; - static int[][] map; //숫자판 정보 + static class Node implements Comparable { + int v, w; + + Node() {} + Node(int v, int w) { + this.v = v; + this.w = w; + } + @Override + public int compareTo(Node other) { + return this.w - other.w; + } + } - static boolean[][] visited; //방문체크 + static final int MAX_N = 1000; + static final int INF = 10_000 * MAX_N; - static int max; //최댓값 + static int N, M, X; + static List[] adj = new List[MAX_N + 1]; + static List[] iAdj = new List[MAX_N + 1]; + static int[] minDist = new int[MAX_N + 1]; + static int[] iMinDist = new int[MAX_N + 1]; - public static void main(String[] args) throws IOException { - BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + static void dijkstra(int s, List[] adj, int[] minDist) { + PriorityQueue q = new PriorityQueue<>(); + q.offer(new Node(s, 0)); + minDist[s] = 0; - StringTokenizer st = new StringTokenizer(br.readLine()); - - N = Integer.parseInt(st.nextToken()); - M = Integer.parseInt(st.nextToken()); - - //탐색의 편이를 위해 공백을 넣어놓음 - map = new int[N+2][M+2]; - for(int i=1; i<=N; i++) { - st = new StringTokenizer(br.readLine()); - for(int j=1; j<=M; j++) { - map[i][j] = Integer.parseInt(st.nextToken()); + while(!q.isEmpty()) { + Node node = q.poll(); + int u = node.v, w = node.w; + + for(Node nextNode : adj[u]) { + int v = nextNode.v; + int dist = nextNode.w + w; + if(dist < minDist[v]) { + minDist[v] = dist; + q.offer(new Node(v, dist)); + } } } + } + + static int solution() { + dijkstra(X, adj, minDist); + dijkstra(X, iAdj, iMinDist); - - visited = new boolean[N+2][M+2]; - - - for(int i=1; i<=N; i++) { - for(int j=1; j<=M; j++) { - visited[i][j] = true; - dfs(i,j, map[i][j], 1); - visited[i][j] = false; - - //가운데 블록 기준 3개 블록이 붙어있는 테트로미노 탐색 - etc(i, j, map[i][j]); - } + int max = Integer.MIN_VALUE; + for(int i = 1; i <= N; ++i) { + max = Math.max(max, minDist[i] + iMinDist[i]); } - - System.out.println(max); + return max; } - - //가운데 블록 기준 3개 블록이 붙어있는 테트로미노 탐색 - private static void etc(int r, int c, int sum) { + + public static void main(String[] args) throws IOException { + st = new StringTokenizer(br.readLine()); + N = Integer.parseInt(st.nextToken()); + M = Integer.parseInt(st.nextToken()); + X = Integer.parseInt(st.nextToken()); - //(r,c) 기준 4방의 값을 모두 더함 - for(int d=0; d<4; d++) { - int nr = r+dr[d]; - int nc = c+dc[d]; - sum+= map[nr][nc]; - } - //4방의 값을 하나씩 빼보면서 해당 값이 최댓값이라면 갱신 - for(int d=0; d<4; d++) { - int nr = r+dr[d]; - int nc = c+dc[d]; - max = Math.max(max, sum-map[nr][nc]); - } - } - - /** - * 블록하나를 선택하고 다음 블록 선택은 재귀호출로 넘김 - * @param r - * @param c - * @param sum //선택한 블록의 숫자 합 - * @param cnt //선택한 블록의 개수 - */ - private static void dfs(int r, int c, int sum, int cnt) { - - //step01. 4개의 블록 선택 완료 - if(cnt==4) { - //step 02. 선택한 블록 숫자의 합이 최댓값이라면 갱신 - max = Math.max(sum, max); - return; + for(int i = 1; i <= N; ++i) { + adj[i] = new ArrayList<>(); + iAdj[i] = new ArrayList<>(); } + Arrays.fill(minDist, INF); + Arrays.fill(iMinDist, INF); - //윗 방향을 제외한 3방향으로 이동하며 블록 선택 - for(int d=0; d<3; d++) { - - int nr = r+dr[d]; - int nc = c+dc[d]; - - //경계를 벗어나거나 이미 방문했다면 다음 방향 - if(nr>N || nc<1 || nc>M || visited[nr][nc]) continue; - - visited[nr][nc] = true; - dfs(nr, nc, sum+map[nr][nc], cnt+1); - visited[nr][nc] = false; + for(int i = 0; i < M; ++i) { + st = new StringTokenizer(br.readLine()); + int u = Integer.parseInt(st.nextToken()); + int v = Integer.parseInt(st.nextToken()); + int w = Integer.parseInt(st.nextToken()); + adj[u].add(new Node(v, w)); + iAdj[v].add(new Node(u, w)); } + System.out.println(solution()); } - - - } diff --git a/week10/Baekjoon13549.java b/week10/Baekjoon13549.java index 150a6ca..6c90ae9 100644 --- a/week10/Baekjoon13549.java +++ b/week10/Baekjoon13549.java @@ -1,7 +1,62 @@ +import java.io.*; +import java.util.*; -public class Main { +/* + * 메모리: 22,676KB + * 시간: 132ms + */ +public class Baekjoon13549 { + // Input Handler + static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + static StringBuilder sb = new StringBuilder(); + static StringTokenizer st; + // constants + static final int SIZE = 200_100; + // variables + static int N, K; + static int[] isVisited = new int[SIZE + 1]; + + static boolean isValid(int x) { + return 0 <= x && x < SIZE && isVisited[x] == -1; + } + + static void solution() { + Arrays.fill(isVisited, -1); + Deque q = new ArrayDeque(); + q.offerLast(N); + isVisited[N] = 0; + + while (!q.isEmpty()) { + int x = q.pollFirst(); + if (x == K) return; + + for(int nx : new int[] {x-1, x+1, x<<1}) { + if(isValid(nx)) { + if(nx == x<<1) { + q.offerFirst(nx); + isVisited[nx] = isVisited[x]; + } else { + q.offerLast(nx); + isVisited[nx] = isVisited[x] + 1; + } + } + } + } + } + + public static void main(String[] args) throws IOException { + N = readInt(); + K = readInt(); + solution(); + System.out.print(isVisited[K]); + } - public static void main(String[] args) { - + static int readInt() throws IOException { + int c, n = 0; + while ((c = System.in.read()) >= 0x30) + n = (n << 3) + (n << 1) + (c & 0x0F); + if (c == '\r') + System.in.read(); + return n; } } diff --git a/week10/Baekjoon15486.java b/week10/Baekjoon15486.java index 150a6ca..b327dd5 100644 --- a/week10/Baekjoon15486.java +++ b/week10/Baekjoon15486.java @@ -1,7 +1,45 @@ +import java.io.*; +import java.util.*; -public class Main { - - public static void main(String[] args) { - +/* + * 메모리: 29,732KB + * 시간: 296ms + */ +public class Baekjoon15486 { + // Input Handler + static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + static StringBuilder sb = new StringBuilder(); + static StringTokenizer st; + // types + // constants + static int MAX_N = 1_500_000; + // variables + static int N; + static int[] T = new int[MAX_N + 10]; // 상담 소요 일수 + static int[] P = new int[MAX_N + 10]; // 수임료 + static int[] dp = new int[MAX_N + 10]; // i일부터 N일까지 얻을 수 있는 최대 수임료 + + static int solution() { + for(int d = N; d > 0; --d) { + dp[d] = dp[d + 1]; + if(d + T[d] - 1 <= N) dp[d] = Math.max(dp[d], dp[d + T[d]] + P[d]); + } + return dp[1]; + } + + public static void main(String[] args) throws IOException { + N = readInt(); + for(int i = 1; i <= N; ++i) { + T[i] = readInt(); + P[i] = readInt(); + } + System.out.print(solution()); + } + + static int readInt() throws IOException { + int c, n = 0; + while((c = System.in.read()) >= 0x30) n = (n << 3) + (n << 1) + (c & 0x0F); + if(c == '\r') System.in.read(); + return n; } -} +} \ No newline at end of file diff --git a/week10/Baekjoon2607.java b/week10/Baekjoon2607.java index 150a6ca..0e3b05e 100644 --- a/week10/Baekjoon2607.java +++ b/week10/Baekjoon2607.java @@ -1,7 +1,52 @@ +import java.io.*; +import java.util.*; -public class Main { - - public static void main(String[] args) { - - } -} +/* + * 메모리: 11,536KB + * 시간: 64ms + */ +public class Baekjoon2607 { + // IO Handler + static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + static StringBuilder sb = new StringBuilder(); + static StringTokenizer st = null; + // types + // constants + // variables + static int N; + static String origin, other; + static int[] originFreq = new int[0x01 << 7]; + static int[] otherFreq = new int[0x01 << 7]; + + public static void main(String[] args) throws IOException { + N = readInt() - 1; + int cnt = 0; + if(N >= 0) { + origin = br.readLine(); + for(char ch : origin.toCharArray()) ++originFreq[ch]; + + while(N-- > 0) { + other = br.readLine(); + System.arraycopy(originFreq, 'A', otherFreq, 'A', 26); + for(char ch : other.toCharArray()) --otherFreq[ch]; + + int cntOne = 0, notZero = 0; + for(int ch = 'A'; ch <= 'Z'; ++ch) { + if(otherFreq[ch] != 0) ++notZero; + if(Math.abs(otherFreq[ch]) == 1) ++cntOne; + } + + if(notZero == cntOne + && (origin.length() == other.length() && cntOne <= 2 + || origin.length() != other.length() && cntOne == 1)) ++cnt; + } + } + System.out.print(cnt); + } + static int readInt() throws IOException { + int c, n = 0; + while((c = System.in.read()) >= 0x30) n = (n << 3) + (n << 1) + (c & 0x0F); + if(c == '\r') System.in.read(); + return n; + } +} \ No newline at end of file diff --git a/week10/Baekjoon9084.java b/week10/Baekjoon9084.java index ee7e1ab..75849fb 100644 --- a/week10/Baekjoon9084.java +++ b/week10/Baekjoon9084.java @@ -1,125 +1,47 @@ +import java.io.*; +import java.util.*; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.StringTokenizer; - -/** - * - * 각 지점을 중심으로 dfs 아래, 왼쪽, 오른쪽 방향으로만 dfs 탐색 depth:4로 - * - 탐색 시 최대값을 발견한다면 갱신 - * 탐색한 지점은 방문 처리 - * - * - * - * 가운데 모양은 따로 탐색 필요 - * - * - * @author SSAFY - * +/* + * 메모리: 11,436KB + * 시간: 64ms */ -public class Main_B_14500_테트로미노_연민호 { - - //하좌우상 - final static int[] dr = {1, 0, 0, -1}; - final static int[] dc = {0, -1, 1, 0}; - - - - static int N; //세로 크기 - static int M; //가로 크기 - - static int[][] map; //숫자판 정보 - - static boolean[][] visited; //방문체크 - - static int max; //최댓값 - - 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 int[N+2][M+2]; - for(int i=1; i<=N; i++) { - st = new StringTokenizer(br.readLine()); - for(int j=1; j<=M; j++) { - map[i][j] = Integer.parseInt(st.nextToken()); - } - } - - - visited = new boolean[N+2][M+2]; - - - for(int i=1; i<=N; i++) { - for(int j=1; j<=M; j++) { - visited[i][j] = true; - dfs(i,j, map[i][j], 1); - visited[i][j] = false; - - //가운데 블록 기준 3개 블록이 붙어있는 테트로미노 탐색 - etc(i, j, map[i][j]); +public class Baekjoon9084 { + // IO Handler + static StringBuilder sb = new StringBuilder(); + // types + // constants + // variables + static int N, M; + static int[] coins = new int[20]; + static int[] dp = new int[10_001]; + + + static int solution() { + Arrays.fill(dp, 1, M + 1, 0); + for(int i = 0; i < N; ++i) { + for(int j = coins[i]; j <= M; ++j) { + dp[j] += dp[j - coins[i]]; } } - - System.out.println(max); - } - - //가운데 블록 기준 3개 블록이 붙어있는 테트로미노 탐색 - private static void etc(int r, int c, int sum) { - - //(r,c) 기준 4방의 값을 모두 더함 - for(int d=0; d<4; d++) { - int nr = r+dr[d]; - int nc = c+dc[d]; - sum+= map[nr][nc]; - } - - //4방의 값을 하나씩 빼보면서 해당 값이 최댓값이라면 갱신 - for(int d=0; d<4; d++) { - int nr = r+dr[d]; - int nc = c+dc[d]; - max = Math.max(max, sum-map[nr][nc]); - } - } - - /** - * 블록하나를 선택하고 다음 블록 선택은 재귀호출로 넘김 - * @param r - * @param c - * @param sum //선택한 블록의 숫자 합 - * @param cnt //선택한 블록의 개수 - */ - private static void dfs(int r, int c, int sum, int cnt) { - - //step01. 4개의 블록 선택 완료 - if(cnt==4) { - //step 02. 선택한 블록 숫자의 합이 최댓값이라면 갱신 - max = Math.max(sum, max); - return; - } - - //윗 방향을 제외한 3방향으로 이동하며 블록 선택 - for(int d=0; d<3; d++) { - - int nr = r+dr[d]; - int nc = c+dc[d]; - - //경계를 벗어나거나 이미 방문했다면 다음 방향 - if(nr>N || nc<1 || nc>M || visited[nr][nc]) continue; - - visited[nr][nc] = true; - dfs(nr, nc, sum+map[nr][nc], cnt+1); - visited[nr][nc] = false; - } - + return dp[M]; } - - -} + public static void main(String[] args) throws IOException { + dp[0] = 1; + int T = readInt(); + while(T-- > 0) { + N = readInt(); + for(int i = 0; i < N; ++i) coins[i] = readInt(); + M = readInt(); + sb.append(solution()).append("\n"); + } + System.out.println(sb); + } + + static int readInt() throws IOException { + int c, n = 0; + while((c = System.in.read()) >= 0x30) n = (n << 3) + (n << 1) + (c & 0x0F); + if(c == '\r') System.in.read(); + return n; + } +} \ No newline at end of file diff --git a/week11/Baekjoon14658.java b/week11/Baekjoon14658.java index ee7e1ab..da3060f 100644 --- a/week11/Baekjoon14658.java +++ b/week11/Baekjoon14658.java @@ -1,125 +1,57 @@ +import java.io.*; +import java.util.*; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.StringTokenizer; - -/** - * - * 각 지점을 중심으로 dfs 아래, 왼쪽, 오른쪽 방향으로만 dfs 탐색 depth:4로 - * - 탐색 시 최대값을 발견한다면 갱신 - * 탐색한 지점은 방문 처리 - * - * - * - * 가운데 모양은 따로 탐색 필요 - * - * - * @author SSAFY - * +/* + * 메모리: 11,740KB + * 시간: 84ms */ -public class Main_B_14500_테트로미노_연민호 { - - //하좌우상 - final static int[] dr = {1, 0, 0, -1}; - final static int[] dc = {0, -1, 1, 0}; - - - - static int N; //세로 크기 - static int M; //가로 크기 - - static int[][] map; //숫자판 정보 - - static boolean[][] visited; //방문체크 - - static int max; //최댓값 +public class Baekjoon14658 { + // IO Handler + static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + static StringBuilder sb = new StringBuilder(); + static StreamTokenizer st = null; + // types + // constants + static final int MAX_K = 100; + // variables + static int N, M, L, K; + static int[] X = new int[MAX_K]; + static int[] Y = new int[MAX_K]; + + + static boolean overlap(int ay, int ax, int y, int x) { + return 0 <= ay - y && ay - y <= L && 0 <= ax - x && ax - x <= L; + } - 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 int[N+2][M+2]; - for(int i=1; i<=N; i++) { - st = new StringTokenizer(br.readLine()); - for(int j=1; j<=M; j++) { - map[i][j] = Integer.parseInt(st.nextToken()); - } - } - - - visited = new boolean[N+2][M+2]; - - - for(int i=1; i<=N; i++) { - for(int j=1; j<=M; j++) { - visited[i][j] = true; - dfs(i,j, map[i][j], 1); - visited[i][j] = false; + static int solution() { + int max = 0; + for(int ix = 0; ix < K; ++ix) { + int x = X[ix]; + for(int iy = 0; iy < K; ++iy) { + int y = Y[iy]; - //가운데 블록 기준 3개 블록이 붙어있는 테트로미노 탐색 - etc(i, j, map[i][j]); + int cnt = 0; + for(int i = 0; i < K; ++i) { + if(overlap(y, x, Y[i], X[i])) ++cnt; + } + max = Math.max(max, cnt); } } - - System.out.println(max); + return max; } - - //가운데 블록 기준 3개 블록이 붙어있는 테트로미노 탐색 - private static void etc(int r, int c, int sum) { - - //(r,c) 기준 4방의 값을 모두 더함 - for(int d=0; d<4; d++) { - int nr = r+dr[d]; - int nc = c+dc[d]; - sum+= map[nr][nc]; - } - - //4방의 값을 하나씩 빼보면서 해당 값이 최댓값이라면 갱신 - for(int d=0; d<4; d++) { - int nr = r+dr[d]; - int nc = c+dc[d]; - max = Math.max(max, sum-map[nr][nc]); - } - } - - /** - * 블록하나를 선택하고 다음 블록 선택은 재귀호출로 넘김 - * @param r - * @param c - * @param sum //선택한 블록의 숫자 합 - * @param cnt //선택한 블록의 개수 - */ - private static void dfs(int r, int c, int sum, int cnt) { - - //step01. 4개의 블록 선택 완료 - if(cnt==4) { - //step 02. 선택한 블록 숫자의 합이 최댓값이라면 갱신 - max = Math.max(sum, max); - return; - } - - //윗 방향을 제외한 3방향으로 이동하며 블록 선택 - for(int d=0; d<3; d++) { - - int nr = r+dr[d]; - int nc = c+dc[d]; - - //경계를 벗어나거나 이미 방문했다면 다음 방향 - if(nr>N || nc<1 || nc>M || visited[nr][nc]) continue; - - visited[nr][nc] = true; - dfs(nr, nc, sum+map[nr][nc], cnt+1); - visited[nr][nc] = false; + + public static void main(String[] args) throws IOException { + N = readInt(); M = readInt(); L = readInt(); K = readInt(); + for(int i = 0; i < K; ++i) { + X[i] = readInt(); Y[i] = readInt(); } - + System.out.print(K-solution()); } - - + static int readInt() throws IOException { + int c, n = 0; + while((c = System.in.read()) >= 0x30) n = (n << 3) + (n << 1) + (c & 0x0F); + //if(c == '\r') System.in.read(); + return n; + } } diff --git a/week11/Baekjoon1520.java b/week11/Baekjoon1520.java index ee7e1ab..fbb246c 100644 --- a/week11/Baekjoon1520.java +++ b/week11/Baekjoon1520.java @@ -1,125 +1,72 @@ +import java.io.*; +import java.util.*; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.StringTokenizer; - -/** - * - * 각 지점을 중심으로 dfs 아래, 왼쪽, 오른쪽 방향으로만 dfs 탐색 depth:4로 - * - 탐색 시 최대값을 발견한다면 갱신 - * 탐색한 지점은 방문 처리 - * - * - * - * 가운데 모양은 따로 탐색 필요 - * - * - * @author SSAFY - * +/* + * 메모리: 14,896KB + * 시간: 116ms */ -public class Main_B_14500_테트로미노_연민호 { - - //하좌우상 - final static int[] dr = {1, 0, 0, -1}; - final static int[] dc = {0, -1, 1, 0}; - - - - static int N; //세로 크기 - static int M; //가로 크기 - - static int[][] map; //숫자판 정보 - - static boolean[][] visited; //방문체크 +public class Baekjoon1520 { + static StringBuilder sb = new StringBuilder(); + // types + static class Node{ + int y, x, d; + public Node(int y, int x, int d) { this.y = y; this.x = x; this.d = d; } + } + // constants + static int SIZE = 500; + static int[][] DELTA = { + { 1, 0}, + {-1, 0}, + { 0, 1}, + { 0, -1}, + }; + // variables + static int M, N; + static int[][] mat = new int[SIZE][SIZE]; + static int[][] dp = new int[SIZE][SIZE]; - static int max; //최댓값 - 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 int[N+2][M+2]; - for(int i=1; i<=N; i++) { - st = new StringTokenizer(br.readLine()); - for(int j=1; j<=M; j++) { - map[i][j] = Integer.parseInt(st.nextToken()); - } - } - - - visited = new boolean[N+2][M+2]; - - - for(int i=1; i<=N; i++) { - for(int j=1; j<=M; j++) { - visited[i][j] = true; - dfs(i,j, map[i][j], 1); - visited[i][j] = false; - - //가운데 블록 기준 3개 블록이 붙어있는 테트로미노 탐색 - etc(i, j, map[i][j]); - } - } - - System.out.println(max); - } - - //가운데 블록 기준 3개 블록이 붙어있는 테트로미노 탐색 - private static void etc(int r, int c, int sum) { - - //(r,c) 기준 4방의 값을 모두 더함 - for(int d=0; d<4; d++) { - int nr = r+dr[d]; - int nc = c+dc[d]; - sum+= map[nr][nc]; - } - - //4방의 값을 하나씩 빼보면서 해당 값이 최댓값이라면 갱신 - for(int d=0; d<4; d++) { - int nr = r+dr[d]; - int nc = c+dc[d]; - max = Math.max(max, sum-map[nr][nc]); - } + static boolean inRange(int y, int x) { + return 0 <= y && y < M && 0 <= x && x < N; } - - /** - * 블록하나를 선택하고 다음 블록 선택은 재귀호출로 넘김 - * @param r - * @param c - * @param sum //선택한 블록의 숫자 합 - * @param cnt //선택한 블록의 개수 - */ - private static void dfs(int r, int c, int sum, int cnt) { - - //step01. 4개의 블록 선택 완료 - if(cnt==4) { - //step 02. 선택한 블록 숫자의 합이 최댓값이라면 갱신 - max = Math.max(sum, max); - return; - } + + static int dfs(int y, int x) { + if(dp[y][x] >= 0) return dp[y][x]; // 이미 도착점까지 도달하는 경로가 계산됨 + if(y == M - 1 && x == N - 1) return dp[y][x] = 1; // 기저: 도착점 도달 - //윗 방향을 제외한 3방향으로 이동하며 블록 선택 - for(int d=0; d<3; d++) { - - int nr = r+dr[d]; - int nc = c+dc[d]; - - //경계를 벗어나거나 이미 방문했다면 다음 방향 - if(nr>N || nc<1 || nc>M || visited[nr][nc]) continue; + dp[y][x] = 0; + int cnt = 0; + for(int d = 0; d < DELTA.length; ++d) { + int nx = x + DELTA[d][0]; + int ny = y + DELTA[d][1]; - visited[nr][nc] = true; - dfs(nr, nc, sum+map[nr][nc], cnt+1); - visited[nr][nc] = false; + if(inRange(ny, nx) && mat[y][x] > mat[ny][nx]) { + cnt += dfs(ny, nx); + } } - + return dp[y][x] = cnt; } + static int solution() { + if(M == 1 && N == 1) return 1; + return dfs(0, 0); + } - -} + public static void main(String[] args) throws IOException { + M = readInt(); N = readInt(); + for(int y = 0; y < M; ++y) { + for(int x = 0; x < N; ++x) { + mat[y][x] = readInt(); + dp[y][x] = -1; + } + } + System.out.print(solution()); + } + + static int readInt() throws IOException { + int c, n = 0; + while((c = System.in.read()) >= 0x30) n = (n << 3) + (n << 1) + (c & 0x0F); + if(c == '\r') System.in.read(); + return n; + } +} \ No newline at end of file diff --git a/week11/Baekjoon1786.java b/week11/Baekjoon1786.java index ee7e1ab..5e529e9 100644 --- a/week11/Baekjoon1786.java +++ b/week11/Baekjoon1786.java @@ -1,125 +1,57 @@ +import java.io.*; +import java.util.*; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.StringTokenizer; - -/** - * - * 각 지점을 중심으로 dfs 아래, 왼쪽, 오른쪽 방향으로만 dfs 탐색 depth:4로 - * - 탐색 시 최대값을 발견한다면 갱신 - * 탐색한 지점은 방문 처리 - * - * - * - * 가운데 모양은 따로 탐색 필요 - * - * - * @author SSAFY - * +/* + * 메모리: 80,936KB + * 시간: 452ms */ -public class Main_B_14500_테트로미노_연민호 { - - //하좌우상 - final static int[] dr = {1, 0, 0, -1}; - final static int[] dc = {0, -1, 1, 0}; - - - - static int N; //세로 크기 - static int M; //가로 크기 - - static int[][] map; //숫자판 정보 - - static boolean[][] visited; //방문체크 - - static int max; //최댓값 - - 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 int[N+2][M+2]; - for(int i=1; i<=N; i++) { - st = new StringTokenizer(br.readLine()); - for(int j=1; j<=M; j++) { - map[i][j] = Integer.parseInt(st.nextToken()); - } - } - - - visited = new boolean[N+2][M+2]; - - - for(int i=1; i<=N; i++) { - for(int j=1; j<=M; j++) { - visited[i][j] = true; - dfs(i,j, map[i][j], 1); - visited[i][j] = false; - - //가운데 블록 기준 3개 블록이 붙어있는 테트로미노 탐색 - etc(i, j, map[i][j]); +public class Baekjoon1786 { + // Input Handler + static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + static StringBuilder sb = new StringBuilder(); + static StringTokenizer st; + // types + // constants + // variables + static String text, pattern; + static List ans = new ArrayList<>(); + + static int[] getZ(String T) { + char[] cT = T.toCharArray(); + int N = cT.length; + + int[] z = new int[cT.length]; + int l = 0, r = 0; + for(int i = 1; i < N; ++i) { + if(i < r) z[i] = Math.min(r - i, z[i - l]); + while(i + z[i] < N && cT[z[i]] == cT[i + z[i]]) ++z[i]; + if(i + z[i] > r) { + l = i; + r = i + z[i]; } } - - System.out.println(max); + return z; } - - //가운데 블록 기준 3개 블록이 붙어있는 테트로미노 탐색 - private static void etc(int r, int c, int sum) { - - //(r,c) 기준 4방의 값을 모두 더함 - for(int d=0; d<4; d++) { - int nr = r+dr[d]; - int nc = c+dc[d]; - sum+= map[nr][nc]; - } + + static void solution() { + int txtLength = text.length(), patLength = pattern.length(); + int[] z = getZ(pattern+"$"+text); - //4방의 값을 하나씩 빼보면서 해당 값이 최댓값이라면 갱신 - for(int d=0; d<4; d++) { - int nr = r+dr[d]; - int nc = c+dc[d]; - max = Math.max(max, sum-map[nr][nc]); + for(int i = 0; i < txtLength; ++i) { + if(z[i + patLength + 1] == patLength) ans.add(i + 1); } } - - /** - * 블록하나를 선택하고 다음 블록 선택은 재귀호출로 넘김 - * @param r - * @param c - * @param sum //선택한 블록의 숫자 합 - * @param cnt //선택한 블록의 개수 - */ - private static void dfs(int r, int c, int sum, int cnt) { - - //step01. 4개의 블록 선택 완료 - if(cnt==4) { - //step 02. 선택한 블록 숫자의 합이 최댓값이라면 갱신 - max = Math.max(sum, max); - return; - } - - //윗 방향을 제외한 3방향으로 이동하며 블록 선택 - for(int d=0; d<3; d++) { - - int nr = r+dr[d]; - int nc = c+dc[d]; - - //경계를 벗어나거나 이미 방문했다면 다음 방향 - if(nr>N || nc<1 || nc>M || visited[nr][nc]) continue; - - visited[nr][nc] = true; - dfs(nr, nc, sum+map[nr][nc], cnt+1); - visited[nr][nc] = false; - } + + public static void main(String[] args) throws IOException { + // Input + text = br.readLine(); + pattern = br.readLine(); + // solution + solution(); + // Output + sb.append(ans.size()).append("\n"); + for(int idx : ans) sb.append(idx).append(" "); + System.out.print(sb); } - - - -} +} \ No newline at end of file diff --git a/week11/Baekjoon2467.java b/week11/Baekjoon2467.java index ee7e1ab..c3a65d2 100644 --- a/week11/Baekjoon2467.java +++ b/week11/Baekjoon2467.java @@ -1,125 +1,60 @@ +import java.io.*; +import java.util.*; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.StringTokenizer; - -/** - * - * 각 지점을 중심으로 dfs 아래, 왼쪽, 오른쪽 방향으로만 dfs 탐색 depth:4로 - * - 탐색 시 최대값을 발견한다면 갱신 - * 탐색한 지점은 방문 처리 - * - * - * - * 가운데 모양은 따로 탐색 필요 - * - * - * @author SSAFY - * +/* + * 메모리: 31,764KB + * 시간: 252ms */ -public class Main_B_14500_테트로미노_연민호 { - - //하좌우상 - final static int[] dr = {1, 0, 0, -1}; - final static int[] dc = {0, -1, 1, 0}; - - - - static int N; //세로 크기 - static int M; //가로 크기 - - static int[][] map; //숫자판 정보 - - static boolean[][] visited; //방문체크 - - static int max; //최댓값 - - 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 int[N+2][M+2]; - for(int i=1; i<=N; i++) { - st = new StringTokenizer(br.readLine()); - for(int j=1; j<=M; j++) { - map[i][j] = Integer.parseInt(st.nextToken()); - } +public class Baekjoon2467 { + // Input Handler + static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out)); + static StringTokenizer st = null; + // constants + // variables + static int N; + static long[] potions; + + static long[] solution(long[] potions) { + Arrays.sort(potions); + if(potions[0] >= 0) { + return new long[] {potions[0], potions[1]}; + } else if(potions[potions.length - 1] <= 0) { + return new long[] {potions[potions.length - 2], potions[potions.length - 1]}; } - visited = new boolean[N+2][M+2]; - - - for(int i=1; i<=N; i++) { - for(int j=1; j<=M; j++) { - visited[i][j] = true; - dfs(i,j, map[i][j], 1); - visited[i][j] = false; - - //가운데 블록 기준 3개 블록이 붙어있는 테트로미노 탐색 - etc(i, j, map[i][j]); + int minL = 0, minR = potions.length - 1; + long minVal = potions[minL] + potions[minR]; + { + int l = minL, r = minR; + while(l + 1 < r) { + long val = potions[l] + potions[r]; + if(val < 0) { + ++l; + } else { + --r; + } + val = potions[l] + potions[r]; + if(Math.abs(val) < Math.abs(minVal)) { + minL = l; + minR = r; + minVal = val; + } } } - - System.out.println(max); - } - - //가운데 블록 기준 3개 블록이 붙어있는 테트로미노 탐색 - private static void etc(int r, int c, int sum) { - - //(r,c) 기준 4방의 값을 모두 더함 - for(int d=0; d<4; d++) { - int nr = r+dr[d]; - int nc = c+dc[d]; - sum+= map[nr][nc]; - } - - //4방의 값을 하나씩 빼보면서 해당 값이 최댓값이라면 갱신 - for(int d=0; d<4; d++) { - int nr = r+dr[d]; - int nc = c+dc[d]; - max = Math.max(max, sum-map[nr][nc]); - } + return new long[] {potions[minL], potions[minR]}; } - - /** - * 블록하나를 선택하고 다음 블록 선택은 재귀호출로 넘김 - * @param r - * @param c - * @param sum //선택한 블록의 숫자 합 - * @param cnt //선택한 블록의 개수 - */ - private static void dfs(int r, int c, int sum, int cnt) { - - //step01. 4개의 블록 선택 완료 - if(cnt==4) { - //step 02. 선택한 블록 숫자의 합이 최댓값이라면 갱신 - max = Math.max(sum, max); - return; - } + + public static void main(String[] args) throws IOException { + N = Integer.parseInt(br.readLine()); + potions = new long[N]; - //윗 방향을 제외한 3방향으로 이동하며 블록 선택 - for(int d=0; d<3; d++) { - - int nr = r+dr[d]; - int nc = c+dc[d]; - - //경계를 벗어나거나 이미 방문했다면 다음 방향 - if(nr>N || nc<1 || nc>M || visited[nr][nc]) continue; - - visited[nr][nc] = true; - dfs(nr, nc, sum+map[nr][nc], cnt+1); - visited[nr][nc] = false; - } + st = new StringTokenizer(br.readLine()); + for(int i = 0; i < N; ++i) potions[i] = Long.parseLong(st.nextToken()); + long[] ret = solution(potions); + bw.append(ret[0] + " " + ret[1]).flush(); } - - - } + \ No newline at end of file diff --git a/week11/Baekjoon2550.java b/week11/Baekjoon2550.java index ee7e1ab..2a0e211 100644 --- a/week11/Baekjoon2550.java +++ b/week11/Baekjoon2550.java @@ -1,125 +1,87 @@ +import java.io.*; +import java.util.*; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.StringTokenizer; - -/** - * - * 각 지점을 중심으로 dfs 아래, 왼쪽, 오른쪽 방향으로만 dfs 탐색 depth:4로 - * - 탐색 시 최대값을 발견한다면 갱신 - * 탐색한 지점은 방문 처리 - * - * - * - * 가운데 모양은 따로 탐색 필요 - * - * - * @author SSAFY - * +/* + * 메모리: 14,080KB + * 시간: 108ms */ -public class Main_B_14500_테트로미노_연민호 { - - //하좌우상 - final static int[] dr = {1, 0, 0, -1}; - final static int[] dc = {0, -1, 1, 0}; - - +public class Baekjoon2550 { + // Input Handler + static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + static StringBuilder sb = new StringBuilder(); + static StringTokenizer st; + // types + // constants + static final int SIZE = 10_000; + // variables + static int N; + static int[] switchToNo = new int[SIZE]; + static int[] bulbToNo = new int[SIZE]; + //static int[] noToSwitch = new int[SIZE+1]; + static int[] noToBulb = new int[SIZE+1]; - static int N; //세로 크기 - static int M; //가로 크기 + static int[] A = new int[SIZE]; + static int len = 0; + static int[] buffer = new int[SIZE]; + static int[] dp = new int[SIZE]; + static int[] lis = new int[SIZE]; - static int[][] map; //숫자판 정보 - - static boolean[][] visited; //방문체크 + /* + * A[i]: i번째 스위치에 대응하는 전구의 위치 + * LIS: A로 생성한 LIS + * LIS[i]를 번호로 매핑한 값이 최종 결과 + */ - static int max; //최댓값 + static int lowerBound(int lo, int hi, int key) { + while(lo < hi) { + int mid = (lo + hi) >> 1; + if(buffer[mid] < key) lo = mid + 1; + else hi = mid; + } + return lo; + } - 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 int[N+2][M+2]; - for(int i=1; i<=N; i++) { - st = new StringTokenizer(br.readLine()); - for(int j=1; j<=M; j++) { - map[i][j] = Integer.parseInt(st.nextToken()); - } + static void solution() { + for(int i = 0; i < N; ++i) { + int at = lowerBound(0, len, A[i]); + if(at == len) ++len; + buffer[at] = A[i]; + dp[i] = at; } - - - visited = new boolean[N+2][M+2]; - - - for(int i=1; i<=N; i++) { - for(int j=1; j<=M; j++) { - visited[i][j] = true; - dfs(i,j, map[i][j], 1); - visited[i][j] = false; - - //가운데 블록 기준 3개 블록이 붙어있는 테트로미노 탐색 - etc(i, j, map[i][j]); + for(int i = N - 1, j = len - 1; j >= 0; --i) { + if(dp[i] == j) { + lis[j--] = bulbToNo[A[i]]; } } - - System.out.println(max); + Arrays.sort(lis, 0, len); } - - //가운데 블록 기준 3개 블록이 붙어있는 테트로미노 탐색 - private static void etc(int r, int c, int sum) { - - //(r,c) 기준 4방의 값을 모두 더함 - for(int d=0; d<4; d++) { - int nr = r+dr[d]; - int nc = c+dc[d]; - sum+= map[nr][nc]; - } - - //4방의 값을 하나씩 빼보면서 해당 값이 최댓값이라면 갱신 - for(int d=0; d<4; d++) { - int nr = r+dr[d]; - int nc = c+dc[d]; - max = Math.max(max, sum-map[nr][nc]); + + public static void main(String[] args) throws IOException { + // Input + N = readInt(); + for(int i = 0; i < N; ++i) { + switchToNo[i] = readInt(); + //noToSwitch[switchToNo[i]] = i; } - } - - /** - * 블록하나를 선택하고 다음 블록 선택은 재귀호출로 넘김 - * @param r - * @param c - * @param sum //선택한 블록의 숫자 합 - * @param cnt //선택한 블록의 개수 - */ - private static void dfs(int r, int c, int sum, int cnt) { - - //step01. 4개의 블록 선택 완료 - if(cnt==4) { - //step 02. 선택한 블록 숫자의 합이 최댓값이라면 갱신 - max = Math.max(sum, max); - return; + for(int i = 0; i < N; ++i) { + bulbToNo[i] = readInt(); + noToBulb[bulbToNo[i]] = i; } + for(int i = 0; i < N; ++i) A[i] = noToBulb[switchToNo[i]]; - //윗 방향을 제외한 3방향으로 이동하며 블록 선택 - for(int d=0; d<3; d++) { - - int nr = r+dr[d]; - int nc = c+dc[d]; - - //경계를 벗어나거나 이미 방문했다면 다음 방향 - if(nr>N || nc<1 || nc>M || visited[nr][nc]) continue; - - visited[nr][nc] = true; - dfs(nr, nc, sum+map[nr][nc], cnt+1); - visited[nr][nc] = false; - } + // solution + solution(); + // output + sb.append(len).append("\n"); + for(int i = 0; i < len; ++i) sb.append(lis[i]).append(" "); + System.out.print(sb); } - - -} + static int readInt() throws IOException{ + int c, n = 0; + while((c = System.in.read()) >= 0x30) n = (n << 3) + (n << 1) + (c & 0x0F); + if(c == '\r') System.in.read(); + return n; + } +} \ No newline at end of file diff --git a/week12/Baekjoon16637.java b/week12/Baekjoon16637.java index ee7e1ab..ac8af39 100644 --- a/week12/Baekjoon16637.java +++ b/week12/Baekjoon16637.java @@ -1,125 +1,50 @@ +import java.io.*; +import java.util.*; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.StringTokenizer; - -/** - * - * 각 지점을 중심으로 dfs 아래, 왼쪽, 오른쪽 방향으로만 dfs 탐색 depth:4로 - * - 탐색 시 최대값을 발견한다면 갱신 - * 탐색한 지점은 방문 처리 - * - * - * - * 가운데 모양은 따로 탐색 필요 - * - * - * @author SSAFY - * +/* + * 메모리: 11,564KB + * 시간: 64ms */ -public class Main_B_14500_테트로미노_연민호 { - - //하좌우상 - final static int[] dr = {1, 0, 0, -1}; - final static int[] dc = {0, -1, 1, 0}; - - - - static int N; //세로 크기 - static int M; //가로 크기 - - static int[][] map; //숫자판 정보 - - static boolean[][] visited; //방문체크 - - static int max; //최댓값 - - 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 int[N+2][M+2]; - for(int i=1; i<=N; i++) { - st = new StringTokenizer(br.readLine()); - for(int j=1; j<=M; j++) { - map[i][j] = Integer.parseInt(st.nextToken()); - } - } - - - visited = new boolean[N+2][M+2]; - - - for(int i=1; i<=N; i++) { - for(int j=1; j<=M; j++) { - visited[i][j] = true; - dfs(i,j, map[i][j], 1); - visited[i][j] = false; - - //가운데 블록 기준 3개 블록이 붙어있는 테트로미노 탐색 - etc(i, j, map[i][j]); - } - } - - System.out.println(max); - } - - //가운데 블록 기준 3개 블록이 붙어있는 테트로미노 탐색 - private static void etc(int r, int c, int sum) { - - //(r,c) 기준 4방의 값을 모두 더함 - for(int d=0; d<4; d++) { - int nr = r+dr[d]; - int nc = c+dc[d]; - sum+= map[nr][nc]; - } - - //4방의 값을 하나씩 빼보면서 해당 값이 최댓값이라면 갱신 - for(int d=0; d<4; d++) { - int nr = r+dr[d]; - int nc = c+dc[d]; - max = Math.max(max, sum-map[nr][nc]); +public class Baekjoon16637 { + // Input Handler + static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + static StringBuilder sb = new StringBuilder(); + static StringTokenizer st; + // constants + // variables + static int N; + static char[] cStmt; + static int result = Integer.MIN_VALUE; + + + static int calc(int lhs, int rhs, char op) { + switch(op) { + case '+': return lhs + rhs; + case '-': return lhs - rhs; + case '*': return lhs * rhs; } + return 0; } - - /** - * 블록하나를 선택하고 다음 블록 선택은 재귀호출로 넘김 - * @param r - * @param c - * @param sum //선택한 블록의 숫자 합 - * @param cnt //선택한 블록의 개수 - */ - private static void dfs(int r, int c, int sum, int cnt) { - - //step01. 4개의 블록 선택 완료 - if(cnt==4) { - //step 02. 선택한 블록 숫자의 합이 최댓값이라면 갱신 - max = Math.max(sum, max); + + static void eachSubset(int idx, int leftNum, char leftOp) { + if(idx >= N) { + result = Math.max(result, leftNum); return; } - //윗 방향을 제외한 3방향으로 이동하며 블록 선택 - for(int d=0; d<3; d++) { - - int nr = r+dr[d]; - int nc = c+dc[d]; - - //경계를 벗어나거나 이미 방문했다면 다음 방향 - if(nr>N || nc<1 || nc>M || visited[nr][nc]) continue; - - visited[nr][nc] = true; - dfs(nr, nc, sum+map[nr][nc], cnt+1); - visited[nr][nc] = false; + int num1 = cStmt[idx] - '0'; + eachSubset(idx + 2, calc(leftNum, num1, leftOp) , cStmt[idx + 1]); + if(idx != N - 1) { + int num2 = cStmt[idx + 2] - '0'; + int concat = calc(num1, num2, cStmt[idx + 1]); + eachSubset(idx + 4, calc(leftNum, concat, leftOp), cStmt[idx + 3]); } - } - - + public static void main(String[] args) throws IOException { + N = Integer.parseInt(br.readLine()); + cStmt = (br.readLine() + " ").toCharArray(); + eachSubset(0, 0, '+'); + System.out.print(result); + } } diff --git a/week12/Baekjoon17281.java b/week12/Baekjoon17281.java index ee7e1ab..4854506 100644 --- a/week12/Baekjoon17281.java +++ b/week12/Baekjoon17281.java @@ -1,125 +1,107 @@ +import java.io.*; +import java.util.*; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.StringTokenizer; - -/** - * - * 각 지점을 중심으로 dfs 아래, 왼쪽, 오른쪽 방향으로만 dfs 탐색 depth:4로 - * - 탐색 시 최대값을 발견한다면 갱신 - * 탐색한 지점은 방문 처리 - * - * - * - * 가운데 모양은 따로 탐색 필요 - * - * - * @author SSAFY - * +/* + * 메모리: 14,616KB + * 시간: 884ms */ -public class Main_B_14500_테트로미노_연민호 { - - //하좌우상 - final static int[] dr = {1, 0, 0, -1}; - final static int[] dc = {0, -1, 1, 0}; - - - - static int N; //세로 크기 - static int M; //가로 크기 +public class Baekjoon17281 { + // Input Handler + static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + static StringBuilder sb = new StringBuilder(); + static StringTokenizer st = null; + // constants + static final int NUM_PLAYER = 9; + static final int MAX_N = 50; + static final int NUM_STONE = 3; + // variables + static int N; + static int[][] hits = new int[MAX_N][NUM_PLAYER]; - static int[][] map; //숫자판 정보 + static int[] perm; // 순열 배열 + static boolean[] isVisited; - static boolean[][] visited; //방문체크 + static boolean[] stones = new boolean[NUM_STONE]; + static int result = 0; // 최대 점수 - static int max; //최댓값 - - public static void main(String[] args) throws IOException { - BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); - - StringTokenizer st = new StringTokenizer(br.readLine()); + static void solution(int[] perm) { + // 야구 + int score = 0; - N = Integer.parseInt(st.nextToken()); - M = Integer.parseInt(st.nextToken()); - - //탐색의 편이를 위해 공백을 넣어놓음 - map = new int[N+2][M+2]; - for(int i=1; i<=N; i++) { - st = new StringTokenizer(br.readLine()); - for(int j=1; j<=M; j++) { - map[i][j] = Integer.parseInt(st.nextToken()); - } - } - - - visited = new boolean[N+2][M+2]; - - - for(int i=1; i<=N; i++) { - for(int j=1; j<=M; j++) { - visited[i][j] = true; - dfs(i,j, map[i][j], 1); - visited[i][j] = false; + int playerCur = 0; + int stoneCur = 0; + for(int e = 0; e < N; ++e) { // e번째 이닝 + // 초기화 + int out = 0; + Arrays.fill(stones, false); + + while(out < 3) { + int playerId = perm[playerCur]; + int hit = hits[e][playerId]; - //가운데 블록 기준 3개 블록이 붙어있는 테트로미노 탐색 - etc(i, j, map[i][j]); + if(hit == 0) { // 아웃 + ++out; + } else { // 진루 + for(int i = 0; i < hit; ++i) { + if(stones[stoneCur]) + ++score; + stones[stoneCur] = i == 0; + stoneCur = (stoneCur + 1) % NUM_STONE; + } + } + playerCur = (playerCur + 1) % NUM_PLAYER; } } - System.out.println(max); + result = Math.max(result, score); } - - //가운데 블록 기준 3개 블록이 붙어있는 테트로미노 탐색 - private static void etc(int r, int c, int sum) { - - //(r,c) 기준 4방의 값을 모두 더함 - for(int d=0; d<4; d++) { - int nr = r+dr[d]; - int nc = c+dc[d]; - sum+= map[nr][nc]; + + static void nextPermutation(int idx, int size) { + if(idx == size) { // 기저 + solution(perm); + return; } - //4방의 값을 하나씩 빼보면서 해당 값이 최댓값이라면 갱신 - for(int d=0; d<4; d++) { - int nr = r+dr[d]; - int nc = c+dc[d]; - max = Math.max(max, sum-map[nr][nc]); + if(perm[idx] >= 0) { // 순열의 4번째 원소는 1번 선수로 고정 + nextPermutation(idx + 1, size); + } else { + for(int i = 0; i < size; ++i) { + if(isVisited[i]) continue; + + isVisited[i] = true; + perm[idx] = i; + nextPermutation(idx + 1, size); + perm[idx] = -1; + isVisited[i] = false; + } } } - - /** - * 블록하나를 선택하고 다음 블록 선택은 재귀호출로 넘김 - * @param r - * @param c - * @param sum //선택한 블록의 숫자 합 - * @param cnt //선택한 블록의 개수 - */ - private static void dfs(int r, int c, int sum, int cnt) { - - //step01. 4개의 블록 선택 완료 - if(cnt==4) { - //step 02. 선택한 블록 숫자의 합이 최댓값이라면 갱신 - max = Math.max(sum, max); - return; + + + public static void main(String[] args) throws IOException { + N = readInt(); + for(int i = 0; i < N; ++i) { + for(int j = 0; j < NUM_PLAYER; ++j) { + hits[i][j] = readInt(); + } } - //윗 방향을 제외한 3방향으로 이동하며 블록 선택 - for(int d=0; d<3; d++) { - - int nr = r+dr[d]; - int nc = c+dc[d]; - - //경계를 벗어나거나 이미 방문했다면 다음 방향 - if(nr>N || nc<1 || nc>M || visited[nr][nc]) continue; - - visited[nr][nc] = true; - dfs(nr, nc, sum+map[nr][nc], cnt+1); - visited[nr][nc] = false; - } + perm = new int[NUM_PLAYER]; // 순열 배열 생성 + Arrays.fill(perm, -1); + perm[3] = 0; // 첫번째 선수가 반드시, 4번 타자 + isVisited = new boolean[NUM_PLAYER]; + isVisited[0] = true; + + nextPermutation(0, NUM_PLAYER); + System.out.print(result); } - - + static int readInt() throws IOException { + int c, n = 0; + while((c = System.in.read()) >= 0x30) n = (n << 3) + (n << 1) + (c & 0x0F); + if(c == '\r') System.in.read(); + return n; + } } + \ No newline at end of file diff --git a/week12/Baekjoon1744.java b/week12/Baekjoon1744.java index ee7e1ab..73a77a9 100644 --- a/week12/Baekjoon1744.java +++ b/week12/Baekjoon1744.java @@ -1,125 +1,50 @@ +import java.io.*; +import java.util.*; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.StringTokenizer; - -/** - * - * 각 지점을 중심으로 dfs 아래, 왼쪽, 오른쪽 방향으로만 dfs 탐색 depth:4로 - * - 탐색 시 최대값을 발견한다면 갱신 - * 탐색한 지점은 방문 처리 - * - * - * - * 가운데 모양은 따로 탐색 필요 - * - * - * @author SSAFY - * +/* + * 메모리: 11,564KB + * 시간: 64ms */ -public class Main_B_14500_테트로미노_연민호 { - - //하좌우상 - final static int[] dr = {1, 0, 0, -1}; - final static int[] dc = {0, -1, 1, 0}; - - - - static int N; //세로 크기 - static int M; //가로 크기 - - static int[][] map; //숫자판 정보 - - static boolean[][] visited; //방문체크 - - static int max; //최댓값 +public class Baekjoon1744 { + // IO Handler + static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + static StringBuilder sb = new StringBuilder(); + static StringTokenizer st = null; + // types + // constants + // variables + static int N; + static PriorityQueue gteq2 = new PriorityQueue(); + static PriorityQueue lteq0 = new PriorityQueue(); + static int cntOne = 0; 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 int[N+2][M+2]; - for(int i=1; i<=N; i++) { - st = new StringTokenizer(br.readLine()); - for(int j=1; j<=M; j++) { - map[i][j] = Integer.parseInt(st.nextToken()); - } - } - - - visited = new boolean[N+2][M+2]; - - - for(int i=1; i<=N; i++) { - for(int j=1; j<=M; j++) { - visited[i][j] = true; - dfs(i,j, map[i][j], 1); - visited[i][j] = false; - - //가운데 블록 기준 3개 블록이 붙어있는 테트로미노 탐색 - etc(i, j, map[i][j]); - } + // Input + N = readInt(); + for(int i = 0; i < N; ++i) { + int v = readInt(); + if(v == 1) ++cntOne; + else if(v >= 2) gteq2.offer(v); + else lteq0.offer(v); } + // Output + int sum = cntOne; + if(gteq2.size() % 2 == 1) sum += gteq2.poll(); + while(!gteq2.isEmpty()) sum += gteq2.poll() * gteq2.poll(); + while(lteq0.size() > 1) sum += lteq0.poll() * lteq0.poll(); + while(lteq0.size() > 0) sum += lteq0.poll(); + System.out.print(sum); - System.out.println(max); } - - //가운데 블록 기준 3개 블록이 붙어있는 테트로미노 탐색 - private static void etc(int r, int c, int sum) { - - //(r,c) 기준 4방의 값을 모두 더함 - for(int d=0; d<4; d++) { - int nr = r+dr[d]; - int nc = c+dc[d]; - sum+= map[nr][nc]; - } - - //4방의 값을 하나씩 빼보면서 해당 값이 최댓값이라면 갱신 - for(int d=0; d<4; d++) { - int nr = r+dr[d]; - int nc = c+dc[d]; - max = Math.max(max, sum-map[nr][nc]); - } - } - - /** - * 블록하나를 선택하고 다음 블록 선택은 재귀호출로 넘김 - * @param r - * @param c - * @param sum //선택한 블록의 숫자 합 - * @param cnt //선택한 블록의 개수 - */ - private static void dfs(int r, int c, int sum, int cnt) { - - //step01. 4개의 블록 선택 완료 - if(cnt==4) { - //step 02. 선택한 블록 숫자의 합이 최댓값이라면 갱신 - max = Math.max(sum, max); - return; - } - - //윗 방향을 제외한 3방향으로 이동하며 블록 선택 - for(int d=0; d<3; d++) { - - int nr = r+dr[d]; - int nc = c+dc[d]; - - //경계를 벗어나거나 이미 방문했다면 다음 방향 - if(nr>N || nc<1 || nc>M || visited[nr][nc]) continue; - - visited[nr][nc] = true; - dfs(nr, nc, sum+map[nr][nc], cnt+1); - visited[nr][nc] = false; + + static int readInt() throws IOException { + int c, n = System.in.read() & 0x0F, s = 1; + if(n == 13) { + s = -1; + n = 0; } - + while((c = System.in.read()) >= 0x30) n = (n << 3) + (n << 1) + (c & 0x0F); + if(c == '\r') System.in.read(); + return n * s; } - - - } diff --git a/week12/Baekjoon19539.java b/week12/Baekjoon19539.java index ee7e1ab..73d8493 100644 --- a/week12/Baekjoon19539.java +++ b/week12/Baekjoon19539.java @@ -1,125 +1,42 @@ +import java.io.*; +import java.util.*; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.StringTokenizer; - -/** - * - * 각 지점을 중심으로 dfs 아래, 왼쪽, 오른쪽 방향으로만 dfs 탐색 depth:4로 - * - 탐색 시 최대값을 발견한다면 갱신 - * 탐색한 지점은 방문 처리 - * - * - * - * 가운데 모양은 따로 탐색 필요 - * - * - * @author SSAFY - * +/* + * 메모리: 12,336KB + * 시간: 96ms */ -public class Main_B_14500_테트로미노_연민호 { - - //하좌우상 - final static int[] dr = {1, 0, 0, -1}; - final static int[] dc = {0, -1, 1, 0}; - - - - static int N; //세로 크기 - static int M; //가로 크기 - - static int[][] map; //숫자판 정보 - - static boolean[][] visited; //방문체크 - - static int max; //최댓값 - - 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 int[N+2][M+2]; - for(int i=1; i<=N; i++) { - st = new StringTokenizer(br.readLine()); - for(int j=1; j<=M; j++) { - map[i][j] = Integer.parseInt(st.nextToken()); - } - } - - - visited = new boolean[N+2][M+2]; - - - for(int i=1; i<=N; i++) { - for(int j=1; j<=M; j++) { - visited[i][j] = true; - dfs(i,j, map[i][j], 1); - visited[i][j] = false; - - //가운데 블록 기준 3개 블록이 붙어있는 테트로미노 탐색 - etc(i, j, map[i][j]); - } - } - - System.out.println(max); - } - - //가운데 블록 기준 3개 블록이 붙어있는 테트로미노 탐색 - private static void etc(int r, int c, int sum) { - - //(r,c) 기준 4방의 값을 모두 더함 - for(int d=0; d<4; d++) { - int nr = r+dr[d]; - int nc = c+dc[d]; - sum+= map[nr][nc]; - } - - //4방의 값을 하나씩 빼보면서 해당 값이 최댓값이라면 갱신 - for(int d=0; d<4; d++) { - int nr = r+dr[d]; - int nc = c+dc[d]; - max = Math.max(max, sum-map[nr][nc]); - } - } - - /** - * 블록하나를 선택하고 다음 블록 선택은 재귀호출로 넘김 - * @param r - * @param c - * @param sum //선택한 블록의 숫자 합 - * @param cnt //선택한 블록의 개수 - */ - private static void dfs(int r, int c, int sum, int cnt) { - - //step01. 4개의 블록 선택 완료 - if(cnt==4) { - //step 02. 선택한 블록 숫자의 합이 최댓값이라면 갱신 - max = Math.max(sum, max); - return; - } - - //윗 방향을 제외한 3방향으로 이동하며 블록 선택 - for(int d=0; d<3; d++) { - - int nr = r+dr[d]; - int nc = c+dc[d]; - - //경계를 벗어나거나 이미 방문했다면 다음 방향 - if(nr>N || nc<1 || nc>M || visited[nr][nc]) continue; - - visited[nr][nc] = true; - dfs(nr, nc, sum+map[nr][nc], cnt+1); - visited[nr][nc] = false; +public class Baekjoon19539 { + // Input Handler + static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + static StringBuilder sb = new StringBuilder(); + static StringTokenizer st; + // types + // constants + // variables + static int N; + static int[] H = new int[100_000]; + + static boolean solution() { + int one = 0, two = 0; + for(int i = 0; i < N; ++i) { + one += H[i] & 1; + two += H[i] >> 1; } - + return (two - one) >= 0 && (two - one) % 3 == 0; } + public static void main(String[] args) throws IOException { + // Input + N = readInt(); + for(int i = 0; i < N; ++i) H[i] = readInt(); + // Output + System.out.println(solution() ? "YES" : "NO"); + } - -} + static int readInt() throws IOException{ + int c, n = 0; + while((c = System.in.read()) >= 0x30) n = (n << 3) + (n << 1) + (c & 0x0F); + if(c == '\r') System.in.read(); + return n; + } +} \ No newline at end of file diff --git a/week12/Baekjoon2589.java b/week12/Baekjoon2589.java index ee7e1ab..228a402 100644 --- a/week12/Baekjoon2589.java +++ b/week12/Baekjoon2589.java @@ -1,125 +1,93 @@ +import java.io.*; +import java.util.*; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.StringTokenizer; - -/** - * - * 각 지점을 중심으로 dfs 아래, 왼쪽, 오른쪽 방향으로만 dfs 탐색 depth:4로 - * - 탐색 시 최대값을 발견한다면 갱신 - * 탐색한 지점은 방문 처리 - * - * - * - * 가운데 모양은 따로 탐색 필요 - * - * - * @author SSAFY - * +/* + * 메모리: 161,604KB + * 시간: 396ms */ -public class Main_B_14500_테트로미노_연민호 { - - //하좌우상 - final static int[] dr = {1, 0, 0, -1}; - final static int[] dc = {0, -1, 1, 0}; - - - - static int N; //세로 크기 - static int M; //가로 크기 +public class Baekjoon2589 { + // Input Handler + static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + static StringBuilder sb = new StringBuilder(); + static StringTokenizer st; + // types + static class Node{ + int x, y, d; // 좌표, 거리 + Node(int x, int y, int d) { this.x=x; this.y=y; this.d=d; } + } - static int[][] map; //숫자판 정보 + // constants + static final char LAND = 'L', WATER = 'W'; + static int[][] DELTA = { + {+1, 0}, + {-1, 0}, + { 0, +1}, + { 0, -1}, + }; + // variables + static int H, W; + static char[][] mat; + static int[][] minDist; - static boolean[][] visited; //방문체크 - static int max; //최댓값 + static boolean inRange(int y, int x) { return 0 <= y && y < H && 0 <= x && x < W; } - 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 int[N+2][M+2]; - for(int i=1; i<=N; i++) { - st = new StringTokenizer(br.readLine()); - for(int j=1; j<=M; j++) { - map[i][j] = Integer.parseInt(st.nextToken()); - } - } - - - visited = new boolean[N+2][M+2]; - - - for(int i=1; i<=N; i++) { - for(int j=1; j<=M; j++) { - visited[i][j] = true; - dfs(i,j, map[i][j], 1); - visited[i][j] = false; + static Node longestPath(int y, int x) { + for(int i = 0; i < H; ++i) Arrays.fill(minDist[i], -1); + Deque q = new ArrayDeque(); + minDist[y][x] = 0; + q.offerLast(new Node(x, y, 0)); + + Node last = null; // 가장 마지막에 방문한 정점 + while(!q.isEmpty()) { + last = q.pollFirst(); + + for(int di = 0; di < DELTA.length; ++di) { + int nx = last.x + DELTA[di][0]; + int ny = last.y + DELTA[di][1]; + if(!inRange(ny, nx) || mat[ny][nx] == WATER || minDist[ny][nx] >= 0) continue; - //가운데 블록 기준 3개 블록이 붙어있는 테트로미노 탐색 - etc(i, j, map[i][j]); + minDist[ny][nx] = last.d + 1; + q.offerLast(new Node(nx, ny, minDist[ny][nx])); } } - - System.out.println(max); + return last; } - - //가운데 블록 기준 3개 블록이 붙어있는 테트로미노 탐색 - private static void etc(int r, int c, int sum) { - - //(r,c) 기준 4방의 값을 모두 더함 - for(int d=0; d<4; d++) { - int nr = r+dr[d]; - int nc = c+dc[d]; - sum+= map[nr][nc]; - } - - //4방의 값을 하나씩 빼보면서 해당 값이 최댓값이라면 갱신 - for(int d=0; d<4; d++) { - int nr = r+dr[d]; - int nc = c+dc[d]; - max = Math.max(max, sum-map[nr][nc]); + + static int solution() { + int max = 0; + for(int y = 0; y < H; ++y) { + for(int x = 0; x < W; ++x) { + if(mat[y][x] == WATER) continue; + Node result = longestPath(y, x); + max = Math.max(max, result.d); + } } + return max; } - - /** - * 블록하나를 선택하고 다음 블록 선택은 재귀호출로 넘김 - * @param r - * @param c - * @param sum //선택한 블록의 숫자 합 - * @param cnt //선택한 블록의 개수 + + + /* + * 각 섬마다 임의의 정점에서 가장 먼 정점을 하나 찾는다. + * 그 정점에서 가장 먼 정점을 찾는다. + * 두 정점사이의 거리가, 각 섬에서 최장 거리이다. */ - private static void dfs(int r, int c, int sum, int cnt) { - - //step01. 4개의 블록 선택 완료 - if(cnt==4) { - //step 02. 선택한 블록 숫자의 합이 최댓값이라면 갱신 - max = Math.max(sum, max); - return; - } + public static void main(String[] args) throws IOException { + // Input + H = readInt(); W = readInt(); + mat = new char[H][]; + minDist = new int[H][W]; - //윗 방향을 제외한 3방향으로 이동하며 블록 선택 - for(int d=0; d<3; d++) { - - int nr = r+dr[d]; - int nc = c+dc[d]; - - //경계를 벗어나거나 이미 방문했다면 다음 방향 - if(nr>N || nc<1 || nc>M || visited[nr][nc]) continue; - - visited[nr][nc] = true; - dfs(nr, nc, sum+map[nr][nc], cnt+1); - visited[nr][nc] = false; - } + for(int y = 0; y < H; ++y) mat[y] = br.readLine().toCharArray(); + // Output + System.out.println(solution()); } - - -} + static int readInt() throws IOException{ + int c, n = 0; + while((c = System.in.read()) >= 0x30) n = (n << 3) + (n << 1) + (c & 0x0F); + if(c == '\r') System.in.read(); + return n; + } +} \ No newline at end of file diff --git a/week13/Baekjoon14725.java b/week13/Baekjoon14725.java index ee7e1ab..42f92c3 100644 --- a/week13/Baekjoon14725.java +++ b/week13/Baekjoon14725.java @@ -1,125 +1,54 @@ - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.StringTokenizer; +import java.io.*; +import java.util.*; /** - * - * 각 지점을 중심으로 dfs 아래, 왼쪽, 오른쪽 방향으로만 dfs 탐색 depth:4로 - * - 탐색 시 최대값을 발견한다면 갱신 - * 탐색한 지점은 방문 처리 - * - * - * - * 가운데 모양은 따로 탐색 필요 - * - * - * @author SSAFY - * + * 개미굴, 14725 + * 메모리: 14,348KB + * 시간: 104ms */ -public class Main_B_14500_테트로미노_연민호 { - - //하좌우상 - final static int[] dr = {1, 0, 0, -1}; - final static int[] dc = {0, -1, 1, 0}; - - - - static int N; //세로 크기 - static int M; //가로 크기 - - static int[][] map; //숫자판 정보 - - static boolean[][] visited; //방문체크 - - static int max; //최댓값 +public class Baekjoon14725 { + // Input Handler + static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + static StringBuilder sb = new StringBuilder(); + static StringTokenizer st; + // constants + static final int SIZE = 10_000; // 단어의 수 + static final int LENGTH = 10; // 단어의 최대 길이 + static final int ROOT = 0; + // types + // variables + static int size = 0; + static Map[] nexts = new Map[SIZE * LENGTH + 1]; + + + static void printHierarchy(int root, int indent) { + for(Map.Entry entry : nexts[root].entrySet()) { + for(int i = 0; i < indent; ++i) sb.append("--"); + sb.append(entry.getKey()).append("\n"); + printHierarchy(entry.getValue(), indent + 1); + } + } public static void main(String[] args) throws IOException { - BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + nexts[ROOT] = new TreeMap<>(); - StringTokenizer st = new StringTokenizer(br.readLine()); - - N = Integer.parseInt(st.nextToken()); - M = Integer.parseInt(st.nextToken()); - - //탐색의 편이를 위해 공백을 넣어놓음 - map = new int[N+2][M+2]; - for(int i=1; i<=N; i++) { + int N = Integer.parseInt(br.readLine()); + while(N-- > 0) { st = new StringTokenizer(br.readLine()); - for(int j=1; j<=M; j++) { - map[i][j] = Integer.parseInt(st.nextToken()); - } - } - - - visited = new boolean[N+2][M+2]; - - - for(int i=1; i<=N; i++) { - for(int j=1; j<=M; j++) { - visited[i][j] = true; - dfs(i,j, map[i][j], 1); - visited[i][j] = false; - - //가운데 블록 기준 3개 블록이 붙어있는 테트로미노 탐색 - etc(i, j, map[i][j]); - } - } - - System.out.println(max); - } - - //가운데 블록 기준 3개 블록이 붙어있는 테트로미노 탐색 - private static void etc(int r, int c, int sum) { - - //(r,c) 기준 4방의 값을 모두 더함 - for(int d=0; d<4; d++) { - int nr = r+dr[d]; - int nc = c+dc[d]; - sum+= map[nr][nc]; - } - - //4방의 값을 하나씩 빼보면서 해당 값이 최댓값이라면 갱신 - for(int d=0; d<4; d++) { - int nr = r+dr[d]; - int nc = c+dc[d]; - max = Math.max(max, sum-map[nr][nc]); - } - } - - /** - * 블록하나를 선택하고 다음 블록 선택은 재귀호출로 넘김 - * @param r - * @param c - * @param sum //선택한 블록의 숫자 합 - * @param cnt //선택한 블록의 개수 - */ - private static void dfs(int r, int c, int sum, int cnt) { - - //step01. 4개의 블록 선택 완료 - if(cnt==4) { - //step 02. 선택한 블록 숫자의 합이 최댓값이라면 갱신 - max = Math.max(sum, max); - return; - } - - //윗 방향을 제외한 3방향으로 이동하며 블록 선택 - for(int d=0; d<3; d++) { - - int nr = r+dr[d]; - int nc = c+dc[d]; + int K = Integer.parseInt(st.nextToken()); - //경계를 벗어나거나 이미 방문했다면 다음 방향 - if(nr>N || nc<1 || nc>M || visited[nr][nc]) continue; - - visited[nr][nc] = true; - dfs(nr, nc, sum+map[nr][nc], cnt+1); - visited[nr][nc] = false; + int cur = ROOT; + while(K-- > 0) { + String alphabet = st.nextToken(); + int nextKey = nexts[cur].getOrDefault(alphabet, size+1); + if(nextKey == size+1) { // 노드 생성 + nexts[cur].put(alphabet, ++size); + nexts[size] = new TreeMap<>(); + } + cur = nextKey; + } } - + printHierarchy(ROOT, 0); + System.out.print(sb); } - - - } diff --git a/week13/Baekjoon2179.java b/week13/Baekjoon2179.java index ee7e1ab..47358ae 100644 --- a/week13/Baekjoon2179.java +++ b/week13/Baekjoon2179.java @@ -1,125 +1,77 @@ - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.StringTokenizer; +import java.io.*; +import java.util.*; /** - * - * 각 지점을 중심으로 dfs 아래, 왼쪽, 오른쪽 방향으로만 dfs 탐색 depth:4로 - * - 탐색 시 최대값을 발견한다면 갱신 - * 탐색한 지점은 방문 처리 - * - * - * - * 가운데 모양은 따로 탐색 필요 - * - * - * @author SSAFY - * + * 비슷한 단어, 2179 + * 메모리: 25,424KB + * 시간: 124ms */ -public class Main_B_14500_테트로미노_연민호 { - - //하좌우상 - final static int[] dr = {1, 0, 0, -1}; - final static int[] dc = {0, -1, 1, 0}; - - - - static int N; //세로 크기 - static int M; //가로 크기 - - static int[][] map; //숫자판 정보 - - static boolean[][] visited; //방문체크 - - static int max; //최댓값 - - 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 int[N+2][M+2]; - for(int i=1; i<=N; i++) { - st = new StringTokenizer(br.readLine()); - for(int j=1; j<=M; j++) { - map[i][j] = Integer.parseInt(st.nextToken()); - } - } - - - visited = new boolean[N+2][M+2]; +public class Baekjoon2179 { + // Input Handler + static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + static StringBuilder sb = new StringBuilder(); + static StringTokenizer st = null; + // constants + static final int SIZE = 20_000; + static final int RANGE = 26; + static final int LENGTH = 100; + // types + static class Node{ + Node[] nexts = new Node[RANGE]; + int conquared; + Node(int no) {this.conquared=no;} + } + // variables + static int N; + static String[] words = new String[SIZE]; + static Node root = new Node(-1); + static int maxLength = 0, maxS = 0, maxT = 1; + + + static void insert(int no, String word) { + char[] cWord = word.toCharArray(); - for(int i=1; i<=N; i++) { - for(int j=1; j<=M; j++) { - visited[i][j] = true; - dfs(i,j, map[i][j], 1); - visited[i][j] = false; + int lcp = 0; + Node cur = root; + for(int i = 0; i < cWord.length; ++i) { + int chi = cWord[i] - 'a'; + + if(cur.nexts[chi] == null) { + cur.nexts[chi] = new Node(no); + } else { + int s = cur.nexts[chi].conquared; + int t = no; - //가운데 블록 기준 3개 블록이 붙어있는 테트로미노 탐색 - etc(i, j, map[i][j]); + ++lcp; + if(lcp > maxLength + || lcp == maxLength && s < maxS + || lcp == maxLength && s == maxS && t < maxT) { + + maxLength = lcp; + maxS = s; + maxT = t; + } } + cur = cur.nexts[chi]; } - - System.out.println(max); - } - - //가운데 블록 기준 3개 블록이 붙어있는 테트로미노 탐색 - private static void etc(int r, int c, int sum) { - - //(r,c) 기준 4방의 값을 모두 더함 - for(int d=0; d<4; d++) { - int nr = r+dr[d]; - int nc = c+dc[d]; - sum+= map[nr][nc]; - } - - //4방의 값을 하나씩 빼보면서 해당 값이 최댓값이라면 갱신 - for(int d=0; d<4; d++) { - int nr = r+dr[d]; - int nc = c+dc[d]; - max = Math.max(max, sum-map[nr][nc]); - } + maxLength = Math.max(maxLength, lcp); } - - /** - * 블록하나를 선택하고 다음 블록 선택은 재귀호출로 넘김 - * @param r - * @param c - * @param sum //선택한 블록의 숫자 합 - * @param cnt //선택한 블록의 개수 - */ - private static void dfs(int r, int c, int sum, int cnt) { - - //step01. 4개의 블록 선택 완료 - if(cnt==4) { - //step 02. 선택한 블록 숫자의 합이 최댓값이라면 갱신 - max = Math.max(sum, max); - return; - } - - //윗 방향을 제외한 3방향으로 이동하며 블록 선택 - for(int d=0; d<3; d++) { - - int nr = r+dr[d]; - int nc = c+dc[d]; - - //경계를 벗어나거나 이미 방문했다면 다음 방향 - if(nr>N || nc<1 || nc>M || visited[nr][nc]) continue; - - visited[nr][nc] = true; - dfs(nr, nc, sum+map[nr][nc], cnt+1); - visited[nr][nc] = false; + + public static void main(String[] args) throws IOException { + N = readInt(); + for(int i = 0; i < N; ++i) { + String word = br.readLine(); + words[i] = word; + insert(i, word); } - + System.out.print(sb.append(words[maxS]).append("\n").append(words[maxT])); } - - + static int readInt() throws IOException { + int c, n = 0; + while((c = System.in.read()) >= 0x30) n = (n << 3) + (n << 1) + (c & 0x0F); + if(c == '\r') System.in.read(); + return n; + } } diff --git a/week13/Baekjoon22860.java b/week13/Baekjoon22860.java index ee7e1ab..de28b70 100644 --- a/week13/Baekjoon22860.java +++ b/week13/Baekjoon22860.java @@ -1,125 +1,85 @@ - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.StringTokenizer; +import java.io.*; +import java.util.*; /** - * - * 각 지점을 중심으로 dfs 아래, 왼쪽, 오른쪽 방향으로만 dfs 탐색 depth:4로 - * - 탐색 시 최대값을 발견한다면 갱신 - * 탐색한 지점은 방문 처리 - * - * - * - * 가운데 모양은 따로 탐색 필요 - * - * - * @author SSAFY - * + * 폴더 정리 (small), 22860 + * 메모리: 88,464KB + * 시간: 544ms */ -public class Main_B_14500_테트로미노_연민호 { - - //하좌우상 - final static int[] dr = {1, 0, 0, -1}; - final static int[] dc = {0, -1, 1, 0}; - +public class Baekjoon22860 { + // Input Handler + static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + static StringBuilder sb = new StringBuilder(); + static StringTokenizer st = null; + // types + static class Node{ + List subDict = new ArrayList(); // 바로 아래에 위치한 폴더 + Set fileNames = new HashSet<>(); // 현재 폴더 이하의 경로에 위치한 파일의 이름들 + int fileNum; // 현재 폴더 이하의 경로에 위치한 파일의 수 + } + // constants + // variables + static int N, M, Q; + static Node root; + // 디렉토리 이름에는 중복이 없다. -> 디렉토리 이름과 인덱스는 1:1 대응관게가 성립 + static Map mapping = new HashMap(); - static int N; //세로 크기 - static int M; //가로 크기 + static Node getNode(String name) { + Node node = mapping.getOrDefault(name, null); + if(node == null) mapping.put(name, node = new Node()); + return node; + } - static int[][] map; //숫자판 정보 + static void insert(String P, String F, int C) { + Node nodeP = getNode(P); + if(C == 0) { // F가 파일 + ++nodeP.fileNum; + nodeP.fileNames.add(F); + } else { // F가 폴더 + Node nodeF = getNode(F); + nodeP.subDict.add(nodeF); + } + } - static boolean[][] visited; //방문체크 + static void build(Node root) { + for(Node next : root.subDict) { + build(next); + root.fileNum += next.fileNum; + root.fileNames.addAll(next.fileNames); + } + } - static int max; //최댓값 + static int[] query(String[] path) { + String target = path[path.length - 1]; + Node node = mapping.get(target); + return new int[] {node.fileNames.size(), node.fileNum}; + } public static void main(String[] args) throws IOException { - BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); - - StringTokenizer st = new StringTokenizer(br.readLine()); + root = new Node(); + mapping.put("main", root); + // 구성 + st = new StringTokenizer(br.readLine()); N = Integer.parseInt(st.nextToken()); M = Integer.parseInt(st.nextToken()); - - //탐색의 편이를 위해 공백을 넣어놓음 - map = new int[N+2][M+2]; - for(int i=1; i<=N; i++) { + for(int i = 0; i < N + M; ++i) { st = new StringTokenizer(br.readLine()); - for(int j=1; j<=M; j++) { - map[i][j] = Integer.parseInt(st.nextToken()); - } - } - - - visited = new boolean[N+2][M+2]; - - - for(int i=1; i<=N; i++) { - for(int j=1; j<=M; j++) { - visited[i][j] = true; - dfs(i,j, map[i][j], 1); - visited[i][j] = false; - - //가운데 블록 기준 3개 블록이 붙어있는 테트로미노 탐색 - etc(i, j, map[i][j]); - } - } - - System.out.println(max); - } - - //가운데 블록 기준 3개 블록이 붙어있는 테트로미노 탐색 - private static void etc(int r, int c, int sum) { - - //(r,c) 기준 4방의 값을 모두 더함 - for(int d=0; d<4; d++) { - int nr = r+dr[d]; - int nc = c+dc[d]; - sum+= map[nr][nc]; - } - - //4방의 값을 하나씩 빼보면서 해당 값이 최댓값이라면 갱신 - for(int d=0; d<4; d++) { - int nr = r+dr[d]; - int nc = c+dc[d]; - max = Math.max(max, sum-map[nr][nc]); - } - } - - /** - * 블록하나를 선택하고 다음 블록 선택은 재귀호출로 넘김 - * @param r - * @param c - * @param sum //선택한 블록의 숫자 합 - * @param cnt //선택한 블록의 개수 - */ - private static void dfs(int r, int c, int sum, int cnt) { - - //step01. 4개의 블록 선택 완료 - if(cnt==4) { - //step 02. 선택한 블록 숫자의 합이 최댓값이라면 갱신 - max = Math.max(sum, max); - return; - } - - //윗 방향을 제외한 3방향으로 이동하며 블록 선택 - for(int d=0; d<3; d++) { - - int nr = r+dr[d]; - int nc = c+dc[d]; + String P = st.nextToken(); + String F = st.nextToken(); + int C = Integer.parseInt(st.nextToken()); - //경계를 벗어나거나 이미 방문했다면 다음 방향 - if(nr>N || nc<1 || nc>M || visited[nr][nc]) continue; - - visited[nr][nc] = true; - dfs(nr, nc, sum+map[nr][nc], cnt+1); - visited[nr][nc] = false; + insert(P, F, C); } - + build(root); + // 쿼리 + Q = Integer.parseInt(br.readLine()); + while(Q-- > 0) { + String[] path = br.readLine().split("/"); + int[] ans = query(path); + sb.append(ans[0]).append(" ").append(ans[1]).append("\n"); + } + System.out.print(sb); } - - - } diff --git a/week13/Baekjoon2866.java b/week13/Baekjoon2866.java index ee7e1ab..4b10113 100644 --- a/week13/Baekjoon2866.java +++ b/week13/Baekjoon2866.java @@ -1,125 +1,79 @@ - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.StringTokenizer; +import java.io.*; +import java.util.*; /** - * - * 각 지점을 중심으로 dfs 아래, 왼쪽, 오른쪽 방향으로만 dfs 탐색 depth:4로 - * - 탐색 시 최대값을 발견한다면 갱신 - * 탐색한 지점은 방문 처리 - * - * - * - * 가운데 모양은 따로 탐색 필요 - * - * - * @author SSAFY - * + * 문자열 잘라내기, 2866 + * 메모리: 151,860KB + * 시간: 320ms */ -public class Main_B_14500_테트로미노_연민호 { - - //하좌우상 - final static int[] dr = {1, 0, 0, -1}; - final static int[] dc = {0, -1, 1, 0}; - - +public class Baekjoon2866 { + // Input Handler + static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + static StringBuilder sb = new StringBuilder(); + static StringTokenizer st; + // types + // constants + static final int SIZE = 1_000; + static final int RANGE = 26; + static final int ROOT = 0; + static final int NPOS = 0; + // variables + static int R, C; + static char[][] mat; - static int N; //세로 크기 - static int M; //가로 크기 + static int size = 0; + static int[] values = new int[SIZE * SIZE + 1]; + static int[][] nexts = new int[SIZE * SIZE + 1][RANGE]; - static int[][] map; //숫자판 정보 - static boolean[][] visited; //방문체크 - - static int max; //최댓값 - - 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 int[N+2][M+2]; - for(int i=1; i<=N; i++) { - st = new StringTokenizer(br.readLine()); - for(int j=1; j<=M; j++) { - map[i][j] = Integer.parseInt(st.nextToken()); - } - } - - - visited = new boolean[N+2][M+2]; - + static int solution() { + int cnt = R - 1; - for(int i=1; i<=N; i++) { - for(int j=1; j<=M; j++) { - visited[i][j] = true; - dfs(i,j, map[i][j], 1); - visited[i][j] = false; + Deque q = new ArrayDeque(); + q.offerLast(ROOT); + while(!q.isEmpty()) { + int width = 0; + for(int i = 0, size = q.size(); i < size; ++i) { + int u = q.pollFirst(); - //가운데 블록 기준 3개 블록이 붙어있는 테트로미노 탐색 - etc(i, j, map[i][j]); + for(int c = 0; c < RANGE; ++c) { + if(nexts[u][c] == 0) continue; + q.offerLast(nexts[u][c]); + ++width; + } } + if(width == C) break; // 레벨에서 방문하는 노드 수가 열의 수와 같으면 중복이 없음 + --cnt; } - - System.out.println(max); + return cnt; } - - //가운데 블록 기준 3개 블록이 붙어있는 테트로미노 탐색 - private static void etc(int r, int c, int sum) { + + public static void main(String[] args) throws IOException { + R = readInt(); C = readInt(); + mat = new char[R][]; + for(int r = 0; r < R; ++r) mat[r] = br.readLine().toCharArray(); - //(r,c) 기준 4방의 값을 모두 더함 - for(int d=0; d<4; d++) { - int nr = r+dr[d]; - int nc = c+dc[d]; - sum+= map[nr][nc]; + // 역방향 트라이 + for(int c = 0; c < C; ++c) { + int cur = ROOT; + for(int r = R - 1; r >= 0; --r) { + int ch = mat[r][c] - 'a'; + + if(nexts[cur][ch] == NPOS) { + values[++size] = ch + 'a'; + nexts[cur][ch] = size; + } + cur = nexts[cur][ch]; + } } - //4방의 값을 하나씩 빼보면서 해당 값이 최댓값이라면 갱신 - for(int d=0; d<4; d++) { - int nr = r+dr[d]; - int nc = c+dc[d]; - max = Math.max(max, sum-map[nr][nc]); - } + System.out.print(solution()); } - /** - * 블록하나를 선택하고 다음 블록 선택은 재귀호출로 넘김 - * @param r - * @param c - * @param sum //선택한 블록의 숫자 합 - * @param cnt //선택한 블록의 개수 - */ - private static void dfs(int r, int c, int sum, int cnt) { - - //step01. 4개의 블록 선택 완료 - if(cnt==4) { - //step 02. 선택한 블록 숫자의 합이 최댓값이라면 갱신 - max = Math.max(sum, max); - return; - } - - //윗 방향을 제외한 3방향으로 이동하며 블록 선택 - for(int d=0; d<3; d++) { - - int nr = r+dr[d]; - int nc = c+dc[d]; - - //경계를 벗어나거나 이미 방문했다면 다음 방향 - if(nr>N || nc<1 || nc>M || visited[nr][nc]) continue; - - visited[nr][nc] = true; - dfs(nr, nc, sum+map[nr][nc], cnt+1); - visited[nr][nc] = false; - } - + static int readInt() throws IOException { + int c, n = 0; + while ((c = System.in.read()) >= 0x30) n = (n << 3) + (n << 1) + (c & 0x0F); + if (c == '\r') System.in.read(); + return n; } - - - } diff --git a/week13/Baekjoon5052.java b/week13/Baekjoon5052.java index ee7e1ab..65eeee3 100644 --- a/week13/Baekjoon5052.java +++ b/week13/Baekjoon5052.java @@ -1,125 +1,67 @@ - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.StringTokenizer; +import java.io.*; +import java.util.*; /** - * - * 각 지점을 중심으로 dfs 아래, 왼쪽, 오른쪽 방향으로만 dfs 탐색 depth:4로 - * - 탐색 시 최대값을 발견한다면 갱신 - * 탐색한 지점은 방문 처리 - * - * - * - * 가운데 모양은 따로 탐색 필요 - * - * - * @author SSAFY - * + * 전화번호 목록, 5052 + * 메모리: 37,936KB + * 시간: 240ms */ -public class Main_B_14500_테트로미노_연민호 { - - //하좌우상 - final static int[] dr = {1, 0, 0, -1}; - final static int[] dc = {0, -1, 1, 0}; - - - - static int N; //세로 크기 - static int M; //가로 크기 +public class Baekjoon5052 { + // Input Handler + static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + static StringBuilder sb = new StringBuilder(); + static StringTokenizer st; + // constants + static final int SIZE = 10_000; // 단어의 수 + static final int LENGTH = 10; // 단어의 최대 길이 + static final int RANGE = 10; // 문자(알파벳)의 수 + static final int ROOT = 0; + static final int[] DEFAULT_NEXTS = new int[RANGE]; + // types + // variables + static int size = 0; + static int[][] nexts = new int[SIZE * LENGTH + 1][RANGE]; + static boolean[] isTerminals = new boolean[SIZE * LENGTH + 1]; + // (트라이의 최대 노드 수) = (단어의 수 * 단어 당 최대 문자의 수) - static int[][] map; //숫자판 정보 - - static boolean[][] visited; //방문체크 - - static int max; //최댓값 - - 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 int[N+2][M+2]; - for(int i=1; i<=N; i++) { - st = new StringTokenizer(br.readLine()); - for(int j=1; j<=M; j++) { - map[i][j] = Integer.parseInt(st.nextToken()); - } - } - - - visited = new boolean[N+2][M+2]; - - - for(int i=1; i<=N; i++) { - for(int j=1; j<=M; j++) { - visited[i][j] = true; - dfs(i,j, map[i][j], 1); - visited[i][j] = false; - - //가운데 블록 기준 3개 블록이 붙어있는 테트로미노 탐색 - etc(i, j, map[i][j]); + static boolean insert(char[] word) { + int cur = ROOT; + for(char ch : word){ + int digit = ch & 0x0F; + if(nexts[cur][digit] == 0) { + nexts[cur][digit] = ++size; } + // 이미 트라이에 존재하어 단어가, 현재 삽입하는 단어의 접두사인지 확인 + if(isTerminals[nexts[cur][digit]]) return false; + + cur = nexts[cur][digit]; } - System.out.println(max); - } - - //가운데 블록 기준 3개 블록이 붙어있는 테트로미노 탐색 - private static void etc(int r, int c, int sum) { - - //(r,c) 기준 4방의 값을 모두 더함 - for(int d=0; d<4; d++) { - int nr = r+dr[d]; - int nc = c+dc[d]; - sum+= map[nr][nc]; - } - - //4방의 값을 하나씩 빼보면서 해당 값이 최댓값이라면 갱신 - for(int d=0; d<4; d++) { - int nr = r+dr[d]; - int nc = c+dc[d]; - max = Math.max(max, sum-map[nr][nc]); - } + isTerminals[cur] = true; + // 현재 삽입하는 단어가 이미 트라이에 존재하는 단어의 접두사인지 확인 + return size == cur; } - - /** - * 블록하나를 선택하고 다음 블록 선택은 재귀호출로 넘김 - * @param r - * @param c - * @param sum //선택한 블록의 숫자 합 - * @param cnt //선택한 블록의 개수 - */ - private static void dfs(int r, int c, int sum, int cnt) { - - //step01. 4개의 블록 선택 완료 - if(cnt==4) { - //step 02. 선택한 블록 숫자의 합이 최댓값이라면 갱신 - max = Math.max(sum, max); - return; - } - - //윗 방향을 제외한 3방향으로 이동하며 블록 선택 - for(int d=0; d<3; d++) { - - int nr = r+dr[d]; - int nc = c+dc[d]; - - //경계를 벗어나거나 이미 방문했다면 다음 방향 - if(nr>N || nc<1 || nc>M || visited[nr][nc]) continue; + + public static void main(String[] args) throws IOException { + int T = Integer.parseInt(br.readLine()); + while(T-- > 0) { + // 초기화: 이전에 사용했던 자원 초기화 + for(int i = 0; i <= size; ++i) { + // Arrays.fill(nexts[i], 0); 보다 빠르다. + System.arraycopy(DEFAULT_NEXTS, 0, nexts[i], 0, RANGE); + } + Arrays.fill(isTerminals, 0, size+1, false); + size = 0; - visited[nr][nc] = true; - dfs(nr, nc, sum+map[nr][nc], cnt+1); - visited[nr][nc] = false; + // Solution + int N = Integer.parseInt(br.readLine()); + boolean pass = true; + while(N-- > 0) { + char[] word = br.readLine().toCharArray(); + pass = pass && insert(word); // 조기 종료 + } + sb.append(pass ? "YES\n" : "NO\n"); } - + System.out.print(sb); } - - - } diff --git a/week14/Baekjoon11437.java b/week14/Baekjoon11437.java deleted file mode 100644 index ee7e1ab..0000000 --- a/week14/Baekjoon11437.java +++ /dev/null @@ -1,125 +0,0 @@ - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.StringTokenizer; - -/** - * - * 각 지점을 중심으로 dfs 아래, 왼쪽, 오른쪽 방향으로만 dfs 탐색 depth:4로 - * - 탐색 시 최대값을 발견한다면 갱신 - * 탐색한 지점은 방문 처리 - * - * - * - * 가운데 모양은 따로 탐색 필요 - * - * - * @author SSAFY - * - */ -public class Main_B_14500_테트로미노_연민호 { - - //하좌우상 - final static int[] dr = {1, 0, 0, -1}; - final static int[] dc = {0, -1, 1, 0}; - - - - static int N; //세로 크기 - static int M; //가로 크기 - - static int[][] map; //숫자판 정보 - - static boolean[][] visited; //방문체크 - - static int max; //최댓값 - - 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 int[N+2][M+2]; - for(int i=1; i<=N; i++) { - st = new StringTokenizer(br.readLine()); - for(int j=1; j<=M; j++) { - map[i][j] = Integer.parseInt(st.nextToken()); - } - } - - - visited = new boolean[N+2][M+2]; - - - for(int i=1; i<=N; i++) { - for(int j=1; j<=M; j++) { - visited[i][j] = true; - dfs(i,j, map[i][j], 1); - visited[i][j] = false; - - //가운데 블록 기준 3개 블록이 붙어있는 테트로미노 탐색 - etc(i, j, map[i][j]); - } - } - - System.out.println(max); - } - - //가운데 블록 기준 3개 블록이 붙어있는 테트로미노 탐색 - private static void etc(int r, int c, int sum) { - - //(r,c) 기준 4방의 값을 모두 더함 - for(int d=0; d<4; d++) { - int nr = r+dr[d]; - int nc = c+dc[d]; - sum+= map[nr][nc]; - } - - //4방의 값을 하나씩 빼보면서 해당 값이 최댓값이라면 갱신 - for(int d=0; d<4; d++) { - int nr = r+dr[d]; - int nc = c+dc[d]; - max = Math.max(max, sum-map[nr][nc]); - } - } - - /** - * 블록하나를 선택하고 다음 블록 선택은 재귀호출로 넘김 - * @param r - * @param c - * @param sum //선택한 블록의 숫자 합 - * @param cnt //선택한 블록의 개수 - */ - private static void dfs(int r, int c, int sum, int cnt) { - - //step01. 4개의 블록 선택 완료 - if(cnt==4) { - //step 02. 선택한 블록 숫자의 합이 최댓값이라면 갱신 - max = Math.max(sum, max); - return; - } - - //윗 방향을 제외한 3방향으로 이동하며 블록 선택 - for(int d=0; d<3; d++) { - - int nr = r+dr[d]; - int nc = c+dc[d]; - - //경계를 벗어나거나 이미 방문했다면 다음 방향 - if(nr>N || nc<1 || nc>M || visited[nr][nc]) continue; - - visited[nr][nc] = true; - dfs(nr, nc, sum+map[nr][nc], cnt+1); - visited[nr][nc] = false; - } - - } - - - -} diff --git a/week14/Baekjoon11437_LCA.java b/week14/Baekjoon11437_LCA.java new file mode 100644 index 0000000..6511e6c --- /dev/null +++ b/week14/Baekjoon11437_LCA.java @@ -0,0 +1,88 @@ +import java.io.*; +import java.util.*; + +/** + * Java8 + * 메모리: 28,928KB + * 시간: 200ms + * + * Java11 + * 메모리: 30,648KB + * 시간: 240ms + * + * @author 배준수 + */ +public class Baekjoon11437_LCA { + // Input Handler + static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + static StringBuilder sb = new StringBuilder(); + static StringTokenizer st = null; + // types + // constants + static final int MAX_N = 50_000; + // variables + static int N, M; + static List[] adj = new List[MAX_N + 1]; + static boolean[] isVisited = new boolean[MAX_N + 1]; + + static int idx = 0; + static int[] inv = new int[MAX_N + 1]; + static int[] depth = new int[MAX_N * 2 - 1]; + static int[] nodes = new int[MAX_N * 2 - 1]; + + static void init(int u, int d) { + isVisited[u] = true; + nodes[idx] = u; + depth[idx] = d; + inv[u] = idx; + ++idx; + + for (int v : adj[u]) { + if (isVisited[v]) continue; + init(v, d + 1); + + nodes[idx] = u; + depth[idx] = d; + inv[u] = idx; + ++idx; + } + } + + static int lca(int u, int v) { + int min = inv[u]; + for (int i = Math.min(inv[u], inv[v]), limit = Math.max(inv[u], inv[v]); i <= limit; ++i) { + if (depth[min] > depth[i]) { + min = i; + } + } + return nodes[min]; + } + + public static void main(String[] args) throws IOException { + N = readInt(); + for (int i = 0; i <= N; ++i) + adj[i] = new ArrayList<>(); + for (int i = 0; i < N - 1; ++i) { + int u = readInt(), v = readInt(); + adj[u].add(v); + adj[v].add(u); + } + init(1, 0); + + M = readInt(); + for (int i = 0; i < M; ++i) { + int u = readInt(), v = readInt(); + sb.append(lca(u, v)).append("\n"); + } + System.out.print(sb); + } + + static int readInt() throws IOException { + int c, n = 0; + while ((c = System.in.read()) >= 0x30) + n = (n << 3) + (n << 1) + (c & 0x0F); + if (c == '\r') + System.in.read(); + return n; + } +} \ No newline at end of file diff --git a/week14/Baekjoon15919.java b/week14/Baekjoon15919.java deleted file mode 100644 index ee7e1ab..0000000 --- a/week14/Baekjoon15919.java +++ /dev/null @@ -1,125 +0,0 @@ - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.StringTokenizer; - -/** - * - * 각 지점을 중심으로 dfs 아래, 왼쪽, 오른쪽 방향으로만 dfs 탐색 depth:4로 - * - 탐색 시 최대값을 발견한다면 갱신 - * 탐색한 지점은 방문 처리 - * - * - * - * 가운데 모양은 따로 탐색 필요 - * - * - * @author SSAFY - * - */ -public class Main_B_14500_테트로미노_연민호 { - - //하좌우상 - final static int[] dr = {1, 0, 0, -1}; - final static int[] dc = {0, -1, 1, 0}; - - - - static int N; //세로 크기 - static int M; //가로 크기 - - static int[][] map; //숫자판 정보 - - static boolean[][] visited; //방문체크 - - static int max; //최댓값 - - 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 int[N+2][M+2]; - for(int i=1; i<=N; i++) { - st = new StringTokenizer(br.readLine()); - for(int j=1; j<=M; j++) { - map[i][j] = Integer.parseInt(st.nextToken()); - } - } - - - visited = new boolean[N+2][M+2]; - - - for(int i=1; i<=N; i++) { - for(int j=1; j<=M; j++) { - visited[i][j] = true; - dfs(i,j, map[i][j], 1); - visited[i][j] = false; - - //가운데 블록 기준 3개 블록이 붙어있는 테트로미노 탐색 - etc(i, j, map[i][j]); - } - } - - System.out.println(max); - } - - //가운데 블록 기준 3개 블록이 붙어있는 테트로미노 탐색 - private static void etc(int r, int c, int sum) { - - //(r,c) 기준 4방의 값을 모두 더함 - for(int d=0; d<4; d++) { - int nr = r+dr[d]; - int nc = c+dc[d]; - sum+= map[nr][nc]; - } - - //4방의 값을 하나씩 빼보면서 해당 값이 최댓값이라면 갱신 - for(int d=0; d<4; d++) { - int nr = r+dr[d]; - int nc = c+dc[d]; - max = Math.max(max, sum-map[nr][nc]); - } - } - - /** - * 블록하나를 선택하고 다음 블록 선택은 재귀호출로 넘김 - * @param r - * @param c - * @param sum //선택한 블록의 숫자 합 - * @param cnt //선택한 블록의 개수 - */ - private static void dfs(int r, int c, int sum, int cnt) { - - //step01. 4개의 블록 선택 완료 - if(cnt==4) { - //step 02. 선택한 블록 숫자의 합이 최댓값이라면 갱신 - max = Math.max(sum, max); - return; - } - - //윗 방향을 제외한 3방향으로 이동하며 블록 선택 - for(int d=0; d<3; d++) { - - int nr = r+dr[d]; - int nc = c+dc[d]; - - //경계를 벗어나거나 이미 방문했다면 다음 방향 - if(nr>N || nc<1 || nc>M || visited[nr][nc]) continue; - - visited[nr][nc] = true; - dfs(nr, nc, sum+map[nr][nc], cnt+1); - visited[nr][nc] = false; - } - - } - - - -} diff --git "a/week14/Baekjoon15919_\354\202\254\354\236\220\353\212\224\354\227\254\355\226\211\354\231\225\354\235\264\354\225\274.java" "b/week14/Baekjoon15919_\354\202\254\354\236\220\353\212\224\354\227\254\355\226\211\354\231\225\354\235\264\354\225\274.java" new file mode 100644 index 0000000..69353e3 --- /dev/null +++ "b/week14/Baekjoon15919_\354\202\254\354\236\220\353\212\224\354\227\254\355\226\211\354\231\225\354\235\264\354\225\274.java" @@ -0,0 +1,78 @@ +import java.io.*; +import java.util.*; + + + +/** + * Java8 + * 메모리: 11,800KB + * 시간: 84ms + * + * Java11 + * 메모리: 14,384KB + * 시간: 120ms + * + * @author 배준수 + */ +public class Baekjoon15919_사자는여행왕이야 { + // Input Handler + static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + static StringBuilder sb = new StringBuilder(); + static StringTokenizer st = null; + // types + static class Travel implements Comparable { + int from, to; + int term; + + public Travel(int from, int to) { + this.from = from; + this.to = to; + this.term = from - 1; // 초기화: 다른 여행을 가지 않음 -> 1 ~ 여행가기 전날 + } + + @Override + public int compareTo(Travel other) { + if(this.from != other.from) return this.from - other.from; + return this.to - other.to; + } + } + // constants + // variables + static int N, M; + static Travel[] travels; + + static int solution() { + // 여행을 마치는 일자 순으로 정렬 + Arrays.sort(travels); + + int min = N; // 여행을 하지 않는 최소 기간의 최댓값 -> 모든 여행을 가지 않음 + for(int i = 0; i < M; ++i) { + Travel target = travels[i]; + + for(int j = 0; j < i; ++j) { // 이전에 갈 수 있는 다른 여행을 탐색 + Travel prev = travels[j]; + if(prev.to >= target.from) continue; + // 여행을 가지 않는 기간 = (이전 여행 일 + 1) ~ (이번 여행 일 - 1) + target.term = Math.min(target.term, Math.max(prev.term, target.from - prev.to - 1)); + } + // 마지막 여행 이후 여행을 가지 않는 기간 = (마지막 여행 일+1) ~ 기간 종료일 + min = Math.min(min, Math.max(target.term, N - target.to)); + } + return min; + } + + public static void main(String[] args) throws IOException { + N = readInt(); + M = readInt(); + travels = new Travel[M]; + for(int i = 0; i < M; ++i) travels[i] = new Travel(readInt(), readInt()); + System.out.print(solution()); + } + + static int readInt() throws IOException { + int c, n = 0; + while((c = System.in.read()) >= 0x30) n = (n << 3) + (n << 1) + (c & 0x0F); + if(c == '\r') System.in.read(); + return n; + } +} \ No newline at end of file diff --git a/week14/Baekjoon15922.java b/week14/Baekjoon15922.java deleted file mode 100644 index ee7e1ab..0000000 --- a/week14/Baekjoon15922.java +++ /dev/null @@ -1,125 +0,0 @@ - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.StringTokenizer; - -/** - * - * 각 지점을 중심으로 dfs 아래, 왼쪽, 오른쪽 방향으로만 dfs 탐색 depth:4로 - * - 탐색 시 최대값을 발견한다면 갱신 - * 탐색한 지점은 방문 처리 - * - * - * - * 가운데 모양은 따로 탐색 필요 - * - * - * @author SSAFY - * - */ -public class Main_B_14500_테트로미노_연민호 { - - //하좌우상 - final static int[] dr = {1, 0, 0, -1}; - final static int[] dc = {0, -1, 1, 0}; - - - - static int N; //세로 크기 - static int M; //가로 크기 - - static int[][] map; //숫자판 정보 - - static boolean[][] visited; //방문체크 - - static int max; //최댓값 - - 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 int[N+2][M+2]; - for(int i=1; i<=N; i++) { - st = new StringTokenizer(br.readLine()); - for(int j=1; j<=M; j++) { - map[i][j] = Integer.parseInt(st.nextToken()); - } - } - - - visited = new boolean[N+2][M+2]; - - - for(int i=1; i<=N; i++) { - for(int j=1; j<=M; j++) { - visited[i][j] = true; - dfs(i,j, map[i][j], 1); - visited[i][j] = false; - - //가운데 블록 기준 3개 블록이 붙어있는 테트로미노 탐색 - etc(i, j, map[i][j]); - } - } - - System.out.println(max); - } - - //가운데 블록 기준 3개 블록이 붙어있는 테트로미노 탐색 - private static void etc(int r, int c, int sum) { - - //(r,c) 기준 4방의 값을 모두 더함 - for(int d=0; d<4; d++) { - int nr = r+dr[d]; - int nc = c+dc[d]; - sum+= map[nr][nc]; - } - - //4방의 값을 하나씩 빼보면서 해당 값이 최댓값이라면 갱신 - for(int d=0; d<4; d++) { - int nr = r+dr[d]; - int nc = c+dc[d]; - max = Math.max(max, sum-map[nr][nc]); - } - } - - /** - * 블록하나를 선택하고 다음 블록 선택은 재귀호출로 넘김 - * @param r - * @param c - * @param sum //선택한 블록의 숫자 합 - * @param cnt //선택한 블록의 개수 - */ - private static void dfs(int r, int c, int sum, int cnt) { - - //step01. 4개의 블록 선택 완료 - if(cnt==4) { - //step 02. 선택한 블록 숫자의 합이 최댓값이라면 갱신 - max = Math.max(sum, max); - return; - } - - //윗 방향을 제외한 3방향으로 이동하며 블록 선택 - for(int d=0; d<3; d++) { - - int nr = r+dr[d]; - int nc = c+dc[d]; - - //경계를 벗어나거나 이미 방문했다면 다음 방향 - if(nr>N || nc<1 || nc>M || visited[nr][nc]) continue; - - visited[nr][nc] = true; - dfs(nr, nc, sum+map[nr][nc], cnt+1); - visited[nr][nc] = false; - } - - } - - - -} diff --git "a/week14/Baekjoon15922_\354\225\204\354\232\260\354\234\274\354\232\260\354\225\204\354\234\274\354\235\264\354\225\274.java" "b/week14/Baekjoon15922_\354\225\204\354\232\260\354\234\274\354\232\260\354\225\204\354\234\274\354\235\264\354\225\274.java" new file mode 100644 index 0000000..ccc4a82 --- /dev/null +++ "b/week14/Baekjoon15922_\354\225\204\354\232\260\354\234\274\354\232\260\354\225\204\354\234\274\354\235\264\354\225\274.java" @@ -0,0 +1,66 @@ +import java.io.*; +import java.util.*; + +/* +[문제] +수직선 위에 선불을 여러 개 그릴 것이다. +선분을 겹치게 그리는 것도 가능하다. +선분을 모두 그렸을 때, 수직선 위에 그려진 선분 길이의 총합은 얼마인지 구하라. + +[입력] +첫째 줄에 수직선 위에 그릴 선분의 개수 N이 주어진다. +둘째 줄 부터 N개의 줄에 좌표를 나타내느 정수쌍(x, y)가 주어진다. +이는 [x, y] 구간 (x와 y를 포함하는 구간)에 선분을 그린하는 의미이다. +좌표는 x가 증가하는 순으로, x가 같다면 y가 증가하는 순으로 주어진다. +(-1,000,000,000 ≤ x < y ≤ 1,000,000,000) + +[출력] +N개의 선분을 모두 그렸을 때, 수직선 위에 그어진 선분 길이의 총합을 출력한다. + */ + + +/** + * Java8 + * 메모리: 12,328KB + * 시간: 136ms + * Java11 + * 메모리: 14,792KB + * 시간: 160ms + * + * @author 배준수 + */ +public class Baekjoon15922_아우으우아으이야 { + // Input Handler + static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + static StringBuilder sb = new StringBuilder(); + static StringTokenizer st = null; + // types + // constants + // variables + static int N; + static int sum; + + public static void main(String[] args) throws IOException { + N = readInt(); + + int right = Integer.MIN_VALUE; + while(N-- > 0) { + int x = readInt(), y = readInt(); + if(y <= right) continue; + sum += y - Math.max(right, x); + right = y; + } + System.out.println(sum); + } + + static int readInt() throws IOException { + int c, n = System.in.read() & 0x0F, s = 1; + if(n == 0x0D) { + s = -1; + n = 0; + } + while((c = System.in.read()) >= 0x30) n = (n << 3) + (n << 1) + (c & 0x0F); + if(c == '\r') System.in.read(); + return n * s; + } +} \ No newline at end of file diff --git a/week14/Baekjoon15927.java b/week14/Baekjoon15927.java deleted file mode 100644 index ee7e1ab..0000000 --- a/week14/Baekjoon15927.java +++ /dev/null @@ -1,125 +0,0 @@ - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.StringTokenizer; - -/** - * - * 각 지점을 중심으로 dfs 아래, 왼쪽, 오른쪽 방향으로만 dfs 탐색 depth:4로 - * - 탐색 시 최대값을 발견한다면 갱신 - * 탐색한 지점은 방문 처리 - * - * - * - * 가운데 모양은 따로 탐색 필요 - * - * - * @author SSAFY - * - */ -public class Main_B_14500_테트로미노_연민호 { - - //하좌우상 - final static int[] dr = {1, 0, 0, -1}; - final static int[] dc = {0, -1, 1, 0}; - - - - static int N; //세로 크기 - static int M; //가로 크기 - - static int[][] map; //숫자판 정보 - - static boolean[][] visited; //방문체크 - - static int max; //최댓값 - - 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 int[N+2][M+2]; - for(int i=1; i<=N; i++) { - st = new StringTokenizer(br.readLine()); - for(int j=1; j<=M; j++) { - map[i][j] = Integer.parseInt(st.nextToken()); - } - } - - - visited = new boolean[N+2][M+2]; - - - for(int i=1; i<=N; i++) { - for(int j=1; j<=M; j++) { - visited[i][j] = true; - dfs(i,j, map[i][j], 1); - visited[i][j] = false; - - //가운데 블록 기준 3개 블록이 붙어있는 테트로미노 탐색 - etc(i, j, map[i][j]); - } - } - - System.out.println(max); - } - - //가운데 블록 기준 3개 블록이 붙어있는 테트로미노 탐색 - private static void etc(int r, int c, int sum) { - - //(r,c) 기준 4방의 값을 모두 더함 - for(int d=0; d<4; d++) { - int nr = r+dr[d]; - int nc = c+dc[d]; - sum+= map[nr][nc]; - } - - //4방의 값을 하나씩 빼보면서 해당 값이 최댓값이라면 갱신 - for(int d=0; d<4; d++) { - int nr = r+dr[d]; - int nc = c+dc[d]; - max = Math.max(max, sum-map[nr][nc]); - } - } - - /** - * 블록하나를 선택하고 다음 블록 선택은 재귀호출로 넘김 - * @param r - * @param c - * @param sum //선택한 블록의 숫자 합 - * @param cnt //선택한 블록의 개수 - */ - private static void dfs(int r, int c, int sum, int cnt) { - - //step01. 4개의 블록 선택 완료 - if(cnt==4) { - //step 02. 선택한 블록 숫자의 합이 최댓값이라면 갱신 - max = Math.max(sum, max); - return; - } - - //윗 방향을 제외한 3방향으로 이동하며 블록 선택 - for(int d=0; d<3; d++) { - - int nr = r+dr[d]; - int nc = c+dc[d]; - - //경계를 벗어나거나 이미 방문했다면 다음 방향 - if(nr>N || nc<1 || nc>M || visited[nr][nc]) continue; - - visited[nr][nc] = true; - dfs(nr, nc, sum+map[nr][nc], cnt+1); - visited[nr][nc] = false; - } - - } - - - -} diff --git "a/week14/Baekjoon15927_\355\232\214\353\254\270\354\235\200\355\232\214\353\254\270\354\225\204\353\213\210\354\225\274.java" "b/week14/Baekjoon15927_\355\232\214\353\254\270\354\235\200\355\232\214\353\254\270\354\225\204\353\213\210\354\225\274.java" new file mode 100644 index 0000000..a51ad2e --- /dev/null +++ "b/week14/Baekjoon15927_\355\232\214\353\254\270\354\235\200\355\232\214\353\254\270\354\225\204\353\213\210\354\225\274.java" @@ -0,0 +1,42 @@ +import java.io.*; +import java.util.*; + +/** + * Java8 + * 메모리: 20,592KB + * 시간: 140ms + * + * @author 배준수 + */ +public class Baekjoon15927_회문은회문아니야 { + // Input Handler + static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + static StringBuilder sb = new StringBuilder(); + static StringTokenizer st = null; + // types + // constants + // variables + + static boolean allTheSame(String s) { + char first = s.charAt(0); + for (char ch : s.toCharArray()) { + if (first != ch) + return false; + } + return true; + } + + static boolean isPalindrome(String s) { + return s.equals(new StringBuilder().append(s).reverse().toString()); + } + + public static void main(String[] args) throws IOException { + String S = br.readLine(); + if (allTheSame(S)) + System.out.print(-1); + else if (isPalindrome(S)) + System.out.print(S.length() - 1); + else + System.out.print(S.length()); + } +} \ No newline at end of file diff --git a/week14/Baekjoon28423.java b/week14/Baekjoon28423.java deleted file mode 100644 index ee7e1ab..0000000 --- a/week14/Baekjoon28423.java +++ /dev/null @@ -1,125 +0,0 @@ - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.StringTokenizer; - -/** - * - * 각 지점을 중심으로 dfs 아래, 왼쪽, 오른쪽 방향으로만 dfs 탐색 depth:4로 - * - 탐색 시 최대값을 발견한다면 갱신 - * 탐색한 지점은 방문 처리 - * - * - * - * 가운데 모양은 따로 탐색 필요 - * - * - * @author SSAFY - * - */ -public class Main_B_14500_테트로미노_연민호 { - - //하좌우상 - final static int[] dr = {1, 0, 0, -1}; - final static int[] dc = {0, -1, 1, 0}; - - - - static int N; //세로 크기 - static int M; //가로 크기 - - static int[][] map; //숫자판 정보 - - static boolean[][] visited; //방문체크 - - static int max; //최댓값 - - 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 int[N+2][M+2]; - for(int i=1; i<=N; i++) { - st = new StringTokenizer(br.readLine()); - for(int j=1; j<=M; j++) { - map[i][j] = Integer.parseInt(st.nextToken()); - } - } - - - visited = new boolean[N+2][M+2]; - - - for(int i=1; i<=N; i++) { - for(int j=1; j<=M; j++) { - visited[i][j] = true; - dfs(i,j, map[i][j], 1); - visited[i][j] = false; - - //가운데 블록 기준 3개 블록이 붙어있는 테트로미노 탐색 - etc(i, j, map[i][j]); - } - } - - System.out.println(max); - } - - //가운데 블록 기준 3개 블록이 붙어있는 테트로미노 탐색 - private static void etc(int r, int c, int sum) { - - //(r,c) 기준 4방의 값을 모두 더함 - for(int d=0; d<4; d++) { - int nr = r+dr[d]; - int nc = c+dc[d]; - sum+= map[nr][nc]; - } - - //4방의 값을 하나씩 빼보면서 해당 값이 최댓값이라면 갱신 - for(int d=0; d<4; d++) { - int nr = r+dr[d]; - int nc = c+dc[d]; - max = Math.max(max, sum-map[nr][nc]); - } - } - - /** - * 블록하나를 선택하고 다음 블록 선택은 재귀호출로 넘김 - * @param r - * @param c - * @param sum //선택한 블록의 숫자 합 - * @param cnt //선택한 블록의 개수 - */ - private static void dfs(int r, int c, int sum, int cnt) { - - //step01. 4개의 블록 선택 완료 - if(cnt==4) { - //step 02. 선택한 블록 숫자의 합이 최댓값이라면 갱신 - max = Math.max(sum, max); - return; - } - - //윗 방향을 제외한 3방향으로 이동하며 블록 선택 - for(int d=0; d<3; d++) { - - int nr = r+dr[d]; - int nc = c+dc[d]; - - //경계를 벗어나거나 이미 방문했다면 다음 방향 - if(nr>N || nc<1 || nc>M || visited[nr][nc]) continue; - - visited[nr][nc] = true; - dfs(nr, nc, sum+map[nr][nc], cnt+1); - visited[nr][nc] = false; - } - - } - - - -} diff --git "a/week14/Baekjoon28423_\352\262\214\354\236\204.java" "b/week14/Baekjoon28423_\352\262\214\354\236\204.java" new file mode 100644 index 0000000..bce6aea --- /dev/null +++ "b/week14/Baekjoon28423_\352\262\214\354\236\204.java" @@ -0,0 +1,80 @@ +import java.io.*; +import java.util.*; + +/** + * Java8 + * 메모리: 11,836KB + * 시간: 76ms + * + * Java11 + * 메모리: 14,456KB + * 시간: 116ms + * + * @author 배준수 + */ +public class Baekjoon28423_게임 { + // Input Handler + static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + static StringBuilder sb = new StringBuilder(); + static StringTokenizer st = null; + // types + // constants + static final int SIZE = 100_000; + // variables + static boolean[] isVisited = new boolean[SIZE + 1]; + + static int combine(int a, int b) { + int shift = 10; + while (b >= shift) + shift *= 10; + return a * shift + b; + } + + static int getF(int N) { + int x = N; + int a = 0, m = 1; + + while (x > 0) { + int digit = x % 10; + + a += digit; + m *= digit; + + x /= 10; + } + return combine(a, m); + } + + static int getG(int N) { + int f = getF(N); + if (N == f) + return 1; + if (f > SIZE) + return -1; + if (isVisited[N]) + return 0; + + isVisited[N] = true; + int ans = getG(f); + isVisited[N] = false; + return ans; + } + + public static void main(String[] args) throws IOException { + int L = readInt(), R = readInt(); + int sum = 0; + for (int i = L; i <= R; ++i) { + sum += getG(i); + } + System.out.print(sum); + } + + static int readInt() throws IOException { + int c, n = 0; + while ((c = System.in.read()) >= 0x30) + n = (n << 3) + (n << 1) + (c & 0x0F); + if (c == '\r') + System.in.read(); + return n; + } +} \ No newline at end of file diff --git a/week15/Baekjoon10159.java b/week15/Baekjoon10159.java deleted file mode 100644 index ee7e1ab..0000000 --- a/week15/Baekjoon10159.java +++ /dev/null @@ -1,125 +0,0 @@ - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.StringTokenizer; - -/** - * - * 각 지점을 중심으로 dfs 아래, 왼쪽, 오른쪽 방향으로만 dfs 탐색 depth:4로 - * - 탐색 시 최대값을 발견한다면 갱신 - * 탐색한 지점은 방문 처리 - * - * - * - * 가운데 모양은 따로 탐색 필요 - * - * - * @author SSAFY - * - */ -public class Main_B_14500_테트로미노_연민호 { - - //하좌우상 - final static int[] dr = {1, 0, 0, -1}; - final static int[] dc = {0, -1, 1, 0}; - - - - static int N; //세로 크기 - static int M; //가로 크기 - - static int[][] map; //숫자판 정보 - - static boolean[][] visited; //방문체크 - - static int max; //최댓값 - - 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 int[N+2][M+2]; - for(int i=1; i<=N; i++) { - st = new StringTokenizer(br.readLine()); - for(int j=1; j<=M; j++) { - map[i][j] = Integer.parseInt(st.nextToken()); - } - } - - - visited = new boolean[N+2][M+2]; - - - for(int i=1; i<=N; i++) { - for(int j=1; j<=M; j++) { - visited[i][j] = true; - dfs(i,j, map[i][j], 1); - visited[i][j] = false; - - //가운데 블록 기준 3개 블록이 붙어있는 테트로미노 탐색 - etc(i, j, map[i][j]); - } - } - - System.out.println(max); - } - - //가운데 블록 기준 3개 블록이 붙어있는 테트로미노 탐색 - private static void etc(int r, int c, int sum) { - - //(r,c) 기준 4방의 값을 모두 더함 - for(int d=0; d<4; d++) { - int nr = r+dr[d]; - int nc = c+dc[d]; - sum+= map[nr][nc]; - } - - //4방의 값을 하나씩 빼보면서 해당 값이 최댓값이라면 갱신 - for(int d=0; d<4; d++) { - int nr = r+dr[d]; - int nc = c+dc[d]; - max = Math.max(max, sum-map[nr][nc]); - } - } - - /** - * 블록하나를 선택하고 다음 블록 선택은 재귀호출로 넘김 - * @param r - * @param c - * @param sum //선택한 블록의 숫자 합 - * @param cnt //선택한 블록의 개수 - */ - private static void dfs(int r, int c, int sum, int cnt) { - - //step01. 4개의 블록 선택 완료 - if(cnt==4) { - //step 02. 선택한 블록 숫자의 합이 최댓값이라면 갱신 - max = Math.max(sum, max); - return; - } - - //윗 방향을 제외한 3방향으로 이동하며 블록 선택 - for(int d=0; d<3; d++) { - - int nr = r+dr[d]; - int nc = c+dc[d]; - - //경계를 벗어나거나 이미 방문했다면 다음 방향 - if(nr>N || nc<1 || nc>M || visited[nr][nc]) continue; - - visited[nr][nc] = true; - dfs(nr, nc, sum+map[nr][nc], cnt+1); - visited[nr][nc] = false; - } - - } - - - -} diff --git "a/week15/Baekjoon10159_\354\240\200\354\232\270.java" "b/week15/Baekjoon10159_\354\240\200\354\232\270.java" new file mode 100644 index 0000000..c4ffdee --- /dev/null +++ "b/week15/Baekjoon10159_\354\240\200\354\232\270.java" @@ -0,0 +1,59 @@ +import java.io.*; +import java.util.*; +/** + * 메모리: 14172KB + * 시간: 116ms + */ +public class Baekjoon10159_저울 { + // Input Handler + static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + static StringBuilder sb = new StringBuilder(); + static StringTokenizer st = null; + // types + // constants + // variables + static int N, M; + static int[][] adj; + + public static void main(String[] args) throws IOException { + N = readInt(); + + adj = new int[N][N]; + for(int i = 0; i < N; ++i) Arrays.fill(adj[i], Integer.MAX_VALUE); + for(int i = 0; i < N; ++i) adj[i][i] = 0; + + M = readInt(); + for(int i = 0; i < M; ++i) { + int u = readInt() - 1, v = readInt() - 1; + adj[u][v] = 1; + } + + for(int k = 0; k < N; ++k) { + for(int i = 0; i < N; ++i) { + for(int j = 0; j < N; ++j) { + if(adj[i][k] == Integer.MAX_VALUE || adj[k][j] == Integer.MAX_VALUE) continue; + adj[i][j] = Math.min(adj[i][j], adj[i][k] + adj[k][j]); + } + } + } + for(int i = 0; i < N; ++i) { + int cnt = 0; + for(int j = 0; j < N; ++j) { + if(adj[i][j] == Integer.MAX_VALUE && adj[j][i] == Integer.MAX_VALUE) ++cnt; + } + sb.append(cnt).append("\n"); + } + System.out.print(sb); + } + + static int readInt() throws IOException { + int c, n = System.in.read() & 0x0F, s = 1; + if(n == 13) { + s = -1; + n = 0; + } + while((c = System.in.read()) >= 0x30) n = (n << 3) + (n << 1) + (c & 0x0F); + if(c == '\r') System.in.read(); + return n * s; + } +} \ No newline at end of file diff --git a/week15/Baekjoon1253.java b/week15/Baekjoon1253.java deleted file mode 100644 index ee7e1ab..0000000 --- a/week15/Baekjoon1253.java +++ /dev/null @@ -1,125 +0,0 @@ - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.StringTokenizer; - -/** - * - * 각 지점을 중심으로 dfs 아래, 왼쪽, 오른쪽 방향으로만 dfs 탐색 depth:4로 - * - 탐색 시 최대값을 발견한다면 갱신 - * 탐색한 지점은 방문 처리 - * - * - * - * 가운데 모양은 따로 탐색 필요 - * - * - * @author SSAFY - * - */ -public class Main_B_14500_테트로미노_연민호 { - - //하좌우상 - final static int[] dr = {1, 0, 0, -1}; - final static int[] dc = {0, -1, 1, 0}; - - - - static int N; //세로 크기 - static int M; //가로 크기 - - static int[][] map; //숫자판 정보 - - static boolean[][] visited; //방문체크 - - static int max; //최댓값 - - 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 int[N+2][M+2]; - for(int i=1; i<=N; i++) { - st = new StringTokenizer(br.readLine()); - for(int j=1; j<=M; j++) { - map[i][j] = Integer.parseInt(st.nextToken()); - } - } - - - visited = new boolean[N+2][M+2]; - - - for(int i=1; i<=N; i++) { - for(int j=1; j<=M; j++) { - visited[i][j] = true; - dfs(i,j, map[i][j], 1); - visited[i][j] = false; - - //가운데 블록 기준 3개 블록이 붙어있는 테트로미노 탐색 - etc(i, j, map[i][j]); - } - } - - System.out.println(max); - } - - //가운데 블록 기준 3개 블록이 붙어있는 테트로미노 탐색 - private static void etc(int r, int c, int sum) { - - //(r,c) 기준 4방의 값을 모두 더함 - for(int d=0; d<4; d++) { - int nr = r+dr[d]; - int nc = c+dc[d]; - sum+= map[nr][nc]; - } - - //4방의 값을 하나씩 빼보면서 해당 값이 최댓값이라면 갱신 - for(int d=0; d<4; d++) { - int nr = r+dr[d]; - int nc = c+dc[d]; - max = Math.max(max, sum-map[nr][nc]); - } - } - - /** - * 블록하나를 선택하고 다음 블록 선택은 재귀호출로 넘김 - * @param r - * @param c - * @param sum //선택한 블록의 숫자 합 - * @param cnt //선택한 블록의 개수 - */ - private static void dfs(int r, int c, int sum, int cnt) { - - //step01. 4개의 블록 선택 완료 - if(cnt==4) { - //step 02. 선택한 블록 숫자의 합이 최댓값이라면 갱신 - max = Math.max(sum, max); - return; - } - - //윗 방향을 제외한 3방향으로 이동하며 블록 선택 - for(int d=0; d<3; d++) { - - int nr = r+dr[d]; - int nc = c+dc[d]; - - //경계를 벗어나거나 이미 방문했다면 다음 방향 - if(nr>N || nc<1 || nc>M || visited[nr][nc]) continue; - - visited[nr][nc] = true; - dfs(nr, nc, sum+map[nr][nc], cnt+1); - visited[nr][nc] = false; - } - - } - - - -} diff --git "a/week15/Baekjoon1253_\354\242\213\353\213\244.java" "b/week15/Baekjoon1253_\354\242\213\353\213\244.java" new file mode 100644 index 0000000..aed9be0 --- /dev/null +++ "b/week15/Baekjoon1253_\354\242\213\353\213\244.java" @@ -0,0 +1,54 @@ +import java.io.*; +import java.util.*; + +/** + * 메모리: 12664kb + * 시간: 100ms + */ +public class Baekjoon1253_좋다 { + // Input Handler + static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + static StringBuilder sb = new StringBuilder(); + static StringTokenizer st = null; + // types + // constants + // variables + static int N; + static int[] A; + + public static void main(String[] args) throws IOException { + N = readInt(); + A = new int[N]; + for(int i = 0; i < N; ++i) A[i] = readInt(); + Arrays.sort(A); + + int cnt = 0; + for(int i = 0; i < N; ++i) { + + int lcur = 0, rcur = N - 1; + while(lcur < rcur) { + int sum = A[lcur] + A[rcur]; + if(sum < A[i] || lcur == i) { + ++lcur; + } else if(A[i] < sum || rcur == i) { + --rcur; + } else { + ++cnt; + break; + } + } + } + System.out.print(cnt); + } + + static int readInt() throws IOException { + int c, n = System.in.read() & 0x0F, s = 1; + if(n == 13) { + s = -1; + n = 0; + } + while((c = System.in.read()) >= 0x30) n = (n << 3) + (n << 1) + (c & 0x0F); + if(c == '\r') System.in.read(); + return n * s; + } +} \ No newline at end of file diff --git a/week15/Baekjoon2138.java b/week15/Baekjoon2138.java deleted file mode 100644 index ee7e1ab..0000000 --- a/week15/Baekjoon2138.java +++ /dev/null @@ -1,125 +0,0 @@ - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.StringTokenizer; - -/** - * - * 각 지점을 중심으로 dfs 아래, 왼쪽, 오른쪽 방향으로만 dfs 탐색 depth:4로 - * - 탐색 시 최대값을 발견한다면 갱신 - * 탐색한 지점은 방문 처리 - * - * - * - * 가운데 모양은 따로 탐색 필요 - * - * - * @author SSAFY - * - */ -public class Main_B_14500_테트로미노_연민호 { - - //하좌우상 - final static int[] dr = {1, 0, 0, -1}; - final static int[] dc = {0, -1, 1, 0}; - - - - static int N; //세로 크기 - static int M; //가로 크기 - - static int[][] map; //숫자판 정보 - - static boolean[][] visited; //방문체크 - - static int max; //최댓값 - - 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 int[N+2][M+2]; - for(int i=1; i<=N; i++) { - st = new StringTokenizer(br.readLine()); - for(int j=1; j<=M; j++) { - map[i][j] = Integer.parseInt(st.nextToken()); - } - } - - - visited = new boolean[N+2][M+2]; - - - for(int i=1; i<=N; i++) { - for(int j=1; j<=M; j++) { - visited[i][j] = true; - dfs(i,j, map[i][j], 1); - visited[i][j] = false; - - //가운데 블록 기준 3개 블록이 붙어있는 테트로미노 탐색 - etc(i, j, map[i][j]); - } - } - - System.out.println(max); - } - - //가운데 블록 기준 3개 블록이 붙어있는 테트로미노 탐색 - private static void etc(int r, int c, int sum) { - - //(r,c) 기준 4방의 값을 모두 더함 - for(int d=0; d<4; d++) { - int nr = r+dr[d]; - int nc = c+dc[d]; - sum+= map[nr][nc]; - } - - //4방의 값을 하나씩 빼보면서 해당 값이 최댓값이라면 갱신 - for(int d=0; d<4; d++) { - int nr = r+dr[d]; - int nc = c+dc[d]; - max = Math.max(max, sum-map[nr][nc]); - } - } - - /** - * 블록하나를 선택하고 다음 블록 선택은 재귀호출로 넘김 - * @param r - * @param c - * @param sum //선택한 블록의 숫자 합 - * @param cnt //선택한 블록의 개수 - */ - private static void dfs(int r, int c, int sum, int cnt) { - - //step01. 4개의 블록 선택 완료 - if(cnt==4) { - //step 02. 선택한 블록 숫자의 합이 최댓값이라면 갱신 - max = Math.max(sum, max); - return; - } - - //윗 방향을 제외한 3방향으로 이동하며 블록 선택 - for(int d=0; d<3; d++) { - - int nr = r+dr[d]; - int nc = c+dc[d]; - - //경계를 벗어나거나 이미 방문했다면 다음 방향 - if(nr>N || nc<1 || nc>M || visited[nr][nc]) continue; - - visited[nr][nc] = true; - dfs(nr, nc, sum+map[nr][nc], cnt+1); - visited[nr][nc] = false; - } - - } - - - -} diff --git "a/week15/Baekjoon2138_\354\240\204\352\265\254\354\231\200\354\212\244\354\234\204\354\271\230.java" "b/week15/Baekjoon2138_\354\240\204\352\265\254\354\231\200\354\212\244\354\234\204\354\271\230.java" new file mode 100644 index 0000000..9a0f25c --- /dev/null +++ "b/week15/Baekjoon2138_\354\240\204\352\265\254\354\231\200\354\212\244\354\234\204\354\271\230.java" @@ -0,0 +1,65 @@ +import java.io.*; +import java.util.*; + +/** + * 메모리: 15992KB + * 시간108ms + */ +public class Baekjoon2138_전구와스위치 { + // Input Handler + static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + static StringBuilder sb = new StringBuilder(); + static StringTokenizer st = null; + // types + // constants + // variables + static int N; + static boolean[] fromP; + static boolean[] fromN; + static boolean[] to; + + static boolean[] toBooleanArray(char[] cArr) { + boolean[] bArr = new boolean[cArr.length]; + for(int i = 0; i < N; ++i) bArr[i] = cArr[i] == '1'; + return bArr; + } + + public static void main(String[] args) throws IOException { + N = readInt(); + char[] cArr = br.readLine().toCharArray(); + fromP = toBooleanArray(cArr); + fromN = toBooleanArray(cArr); + to = toBooleanArray(cArr = br.readLine().toCharArray()); + + int cntP = 1, cntN = 0; + fromP[0] = !fromP[0]; + fromP[1] = !fromP[1]; + + for(int i = 1; i < N; ++i) { + if(fromP[i-1] != to[i-1]) { + ++cntP; + for(int j = -1; j < 2 && i + j < N; ++j) { + fromP[i + j] = !fromP[i + j]; + } + } + if(fromN[i-1] != to[i-1]) { + ++cntN; + for(int j = -1; j < 2 && i + j < N; ++j) { + fromN[i + j] = !fromN[i + j]; + } + } + } + if(fromP[N-1] == to[N-1] && fromN[N-1] == to[N-1]) { + System.out.print(Math.min(cntP, cntN)); + } else if(fromP[N-1] == to[N-1]) System.out.print(cntP); + else if(fromN[N-1] == to[N-1]) System.out.print(cntN); + else System.out.print(-1); + } + + static int readInt() throws IOException { + int c, n = 0; + while((c = System.in.read()) >= 0x30) n = (n << 3) + (n << 1) + (c & 0x0F); + if(c == '\r') System.in.read(); + return n; + } +} \ No newline at end of file diff --git a/week15/Baekjoon2638.java b/week15/Baekjoon2638.java deleted file mode 100644 index ee7e1ab..0000000 --- a/week15/Baekjoon2638.java +++ /dev/null @@ -1,125 +0,0 @@ - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.StringTokenizer; - -/** - * - * 각 지점을 중심으로 dfs 아래, 왼쪽, 오른쪽 방향으로만 dfs 탐색 depth:4로 - * - 탐색 시 최대값을 발견한다면 갱신 - * 탐색한 지점은 방문 처리 - * - * - * - * 가운데 모양은 따로 탐색 필요 - * - * - * @author SSAFY - * - */ -public class Main_B_14500_테트로미노_연민호 { - - //하좌우상 - final static int[] dr = {1, 0, 0, -1}; - final static int[] dc = {0, -1, 1, 0}; - - - - static int N; //세로 크기 - static int M; //가로 크기 - - static int[][] map; //숫자판 정보 - - static boolean[][] visited; //방문체크 - - static int max; //최댓값 - - 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 int[N+2][M+2]; - for(int i=1; i<=N; i++) { - st = new StringTokenizer(br.readLine()); - for(int j=1; j<=M; j++) { - map[i][j] = Integer.parseInt(st.nextToken()); - } - } - - - visited = new boolean[N+2][M+2]; - - - for(int i=1; i<=N; i++) { - for(int j=1; j<=M; j++) { - visited[i][j] = true; - dfs(i,j, map[i][j], 1); - visited[i][j] = false; - - //가운데 블록 기준 3개 블록이 붙어있는 테트로미노 탐색 - etc(i, j, map[i][j]); - } - } - - System.out.println(max); - } - - //가운데 블록 기준 3개 블록이 붙어있는 테트로미노 탐색 - private static void etc(int r, int c, int sum) { - - //(r,c) 기준 4방의 값을 모두 더함 - for(int d=0; d<4; d++) { - int nr = r+dr[d]; - int nc = c+dc[d]; - sum+= map[nr][nc]; - } - - //4방의 값을 하나씩 빼보면서 해당 값이 최댓값이라면 갱신 - for(int d=0; d<4; d++) { - int nr = r+dr[d]; - int nc = c+dc[d]; - max = Math.max(max, sum-map[nr][nc]); - } - } - - /** - * 블록하나를 선택하고 다음 블록 선택은 재귀호출로 넘김 - * @param r - * @param c - * @param sum //선택한 블록의 숫자 합 - * @param cnt //선택한 블록의 개수 - */ - private static void dfs(int r, int c, int sum, int cnt) { - - //step01. 4개의 블록 선택 완료 - if(cnt==4) { - //step 02. 선택한 블록 숫자의 합이 최댓값이라면 갱신 - max = Math.max(sum, max); - return; - } - - //윗 방향을 제외한 3방향으로 이동하며 블록 선택 - for(int d=0; d<3; d++) { - - int nr = r+dr[d]; - int nc = c+dc[d]; - - //경계를 벗어나거나 이미 방문했다면 다음 방향 - if(nr>N || nc<1 || nc>M || visited[nr][nc]) continue; - - visited[nr][nc] = true; - dfs(nr, nc, sum+map[nr][nc], cnt+1); - visited[nr][nc] = false; - } - - } - - - -} diff --git a/week15/Baekjoon2746.java b/week15/Baekjoon2746.java deleted file mode 100644 index ee7e1ab..0000000 --- a/week15/Baekjoon2746.java +++ /dev/null @@ -1,125 +0,0 @@ - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.StringTokenizer; - -/** - * - * 각 지점을 중심으로 dfs 아래, 왼쪽, 오른쪽 방향으로만 dfs 탐색 depth:4로 - * - 탐색 시 최대값을 발견한다면 갱신 - * 탐색한 지점은 방문 처리 - * - * - * - * 가운데 모양은 따로 탐색 필요 - * - * - * @author SSAFY - * - */ -public class Main_B_14500_테트로미노_연민호 { - - //하좌우상 - final static int[] dr = {1, 0, 0, -1}; - final static int[] dc = {0, -1, 1, 0}; - - - - static int N; //세로 크기 - static int M; //가로 크기 - - static int[][] map; //숫자판 정보 - - static boolean[][] visited; //방문체크 - - static int max; //최댓값 - - 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 int[N+2][M+2]; - for(int i=1; i<=N; i++) { - st = new StringTokenizer(br.readLine()); - for(int j=1; j<=M; j++) { - map[i][j] = Integer.parseInt(st.nextToken()); - } - } - - - visited = new boolean[N+2][M+2]; - - - for(int i=1; i<=N; i++) { - for(int j=1; j<=M; j++) { - visited[i][j] = true; - dfs(i,j, map[i][j], 1); - visited[i][j] = false; - - //가운데 블록 기준 3개 블록이 붙어있는 테트로미노 탐색 - etc(i, j, map[i][j]); - } - } - - System.out.println(max); - } - - //가운데 블록 기준 3개 블록이 붙어있는 테트로미노 탐색 - private static void etc(int r, int c, int sum) { - - //(r,c) 기준 4방의 값을 모두 더함 - for(int d=0; d<4; d++) { - int nr = r+dr[d]; - int nc = c+dc[d]; - sum+= map[nr][nc]; - } - - //4방의 값을 하나씩 빼보면서 해당 값이 최댓값이라면 갱신 - for(int d=0; d<4; d++) { - int nr = r+dr[d]; - int nc = c+dc[d]; - max = Math.max(max, sum-map[nr][nc]); - } - } - - /** - * 블록하나를 선택하고 다음 블록 선택은 재귀호출로 넘김 - * @param r - * @param c - * @param sum //선택한 블록의 숫자 합 - * @param cnt //선택한 블록의 개수 - */ - private static void dfs(int r, int c, int sum, int cnt) { - - //step01. 4개의 블록 선택 완료 - if(cnt==4) { - //step 02. 선택한 블록 숫자의 합이 최댓값이라면 갱신 - max = Math.max(sum, max); - return; - } - - //윗 방향을 제외한 3방향으로 이동하며 블록 선택 - for(int d=0; d<3; d++) { - - int nr = r+dr[d]; - int nc = c+dc[d]; - - //경계를 벗어나거나 이미 방문했다면 다음 방향 - if(nr>N || nc<1 || nc>M || visited[nr][nc]) continue; - - visited[nr][nc] = true; - dfs(nr, nc, sum+map[nr][nc], cnt+1); - visited[nr][nc] = false; - } - - } - - - -} diff --git a/week16/Baekjoon16562.java b/week16/Baekjoon16562.java deleted file mode 100644 index ee7e1ab..0000000 --- a/week16/Baekjoon16562.java +++ /dev/null @@ -1,125 +0,0 @@ - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.StringTokenizer; - -/** - * - * 각 지점을 중심으로 dfs 아래, 왼쪽, 오른쪽 방향으로만 dfs 탐색 depth:4로 - * - 탐색 시 최대값을 발견한다면 갱신 - * 탐색한 지점은 방문 처리 - * - * - * - * 가운데 모양은 따로 탐색 필요 - * - * - * @author SSAFY - * - */ -public class Main_B_14500_테트로미노_연민호 { - - //하좌우상 - final static int[] dr = {1, 0, 0, -1}; - final static int[] dc = {0, -1, 1, 0}; - - - - static int N; //세로 크기 - static int M; //가로 크기 - - static int[][] map; //숫자판 정보 - - static boolean[][] visited; //방문체크 - - static int max; //최댓값 - - 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 int[N+2][M+2]; - for(int i=1; i<=N; i++) { - st = new StringTokenizer(br.readLine()); - for(int j=1; j<=M; j++) { - map[i][j] = Integer.parseInt(st.nextToken()); - } - } - - - visited = new boolean[N+2][M+2]; - - - for(int i=1; i<=N; i++) { - for(int j=1; j<=M; j++) { - visited[i][j] = true; - dfs(i,j, map[i][j], 1); - visited[i][j] = false; - - //가운데 블록 기준 3개 블록이 붙어있는 테트로미노 탐색 - etc(i, j, map[i][j]); - } - } - - System.out.println(max); - } - - //가운데 블록 기준 3개 블록이 붙어있는 테트로미노 탐색 - private static void etc(int r, int c, int sum) { - - //(r,c) 기준 4방의 값을 모두 더함 - for(int d=0; d<4; d++) { - int nr = r+dr[d]; - int nc = c+dc[d]; - sum+= map[nr][nc]; - } - - //4방의 값을 하나씩 빼보면서 해당 값이 최댓값이라면 갱신 - for(int d=0; d<4; d++) { - int nr = r+dr[d]; - int nc = c+dc[d]; - max = Math.max(max, sum-map[nr][nc]); - } - } - - /** - * 블록하나를 선택하고 다음 블록 선택은 재귀호출로 넘김 - * @param r - * @param c - * @param sum //선택한 블록의 숫자 합 - * @param cnt //선택한 블록의 개수 - */ - private static void dfs(int r, int c, int sum, int cnt) { - - //step01. 4개의 블록 선택 완료 - if(cnt==4) { - //step 02. 선택한 블록 숫자의 합이 최댓값이라면 갱신 - max = Math.max(sum, max); - return; - } - - //윗 방향을 제외한 3방향으로 이동하며 블록 선택 - for(int d=0; d<3; d++) { - - int nr = r+dr[d]; - int nc = c+dc[d]; - - //경계를 벗어나거나 이미 방문했다면 다음 방향 - if(nr>N || nc<1 || nc>M || visited[nr][nc]) continue; - - visited[nr][nc] = true; - dfs(nr, nc, sum+map[nr][nc], cnt+1); - visited[nr][nc] = false; - } - - } - - - -} diff --git a/week16/Baekjoon1916.java b/week16/Baekjoon1916.java deleted file mode 100644 index ee7e1ab..0000000 --- a/week16/Baekjoon1916.java +++ /dev/null @@ -1,125 +0,0 @@ - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.StringTokenizer; - -/** - * - * 각 지점을 중심으로 dfs 아래, 왼쪽, 오른쪽 방향으로만 dfs 탐색 depth:4로 - * - 탐색 시 최대값을 발견한다면 갱신 - * 탐색한 지점은 방문 처리 - * - * - * - * 가운데 모양은 따로 탐색 필요 - * - * - * @author SSAFY - * - */ -public class Main_B_14500_테트로미노_연민호 { - - //하좌우상 - final static int[] dr = {1, 0, 0, -1}; - final static int[] dc = {0, -1, 1, 0}; - - - - static int N; //세로 크기 - static int M; //가로 크기 - - static int[][] map; //숫자판 정보 - - static boolean[][] visited; //방문체크 - - static int max; //최댓값 - - 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 int[N+2][M+2]; - for(int i=1; i<=N; i++) { - st = new StringTokenizer(br.readLine()); - for(int j=1; j<=M; j++) { - map[i][j] = Integer.parseInt(st.nextToken()); - } - } - - - visited = new boolean[N+2][M+2]; - - - for(int i=1; i<=N; i++) { - for(int j=1; j<=M; j++) { - visited[i][j] = true; - dfs(i,j, map[i][j], 1); - visited[i][j] = false; - - //가운데 블록 기준 3개 블록이 붙어있는 테트로미노 탐색 - etc(i, j, map[i][j]); - } - } - - System.out.println(max); - } - - //가운데 블록 기준 3개 블록이 붙어있는 테트로미노 탐색 - private static void etc(int r, int c, int sum) { - - //(r,c) 기준 4방의 값을 모두 더함 - for(int d=0; d<4; d++) { - int nr = r+dr[d]; - int nc = c+dc[d]; - sum+= map[nr][nc]; - } - - //4방의 값을 하나씩 빼보면서 해당 값이 최댓값이라면 갱신 - for(int d=0; d<4; d++) { - int nr = r+dr[d]; - int nc = c+dc[d]; - max = Math.max(max, sum-map[nr][nc]); - } - } - - /** - * 블록하나를 선택하고 다음 블록 선택은 재귀호출로 넘김 - * @param r - * @param c - * @param sum //선택한 블록의 숫자 합 - * @param cnt //선택한 블록의 개수 - */ - private static void dfs(int r, int c, int sum, int cnt) { - - //step01. 4개의 블록 선택 완료 - if(cnt==4) { - //step 02. 선택한 블록 숫자의 합이 최댓값이라면 갱신 - max = Math.max(sum, max); - return; - } - - //윗 방향을 제외한 3방향으로 이동하며 블록 선택 - for(int d=0; d<3; d++) { - - int nr = r+dr[d]; - int nc = c+dc[d]; - - //경계를 벗어나거나 이미 방문했다면 다음 방향 - if(nr>N || nc<1 || nc>M || visited[nr][nc]) continue; - - visited[nr][nc] = true; - dfs(nr, nc, sum+map[nr][nc], cnt+1); - visited[nr][nc] = false; - } - - } - - - -} diff --git a/week16/Baekjoon2096.java b/week16/Baekjoon2096.java deleted file mode 100644 index ee7e1ab..0000000 --- a/week16/Baekjoon2096.java +++ /dev/null @@ -1,125 +0,0 @@ - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.StringTokenizer; - -/** - * - * 각 지점을 중심으로 dfs 아래, 왼쪽, 오른쪽 방향으로만 dfs 탐색 depth:4로 - * - 탐색 시 최대값을 발견한다면 갱신 - * 탐색한 지점은 방문 처리 - * - * - * - * 가운데 모양은 따로 탐색 필요 - * - * - * @author SSAFY - * - */ -public class Main_B_14500_테트로미노_연민호 { - - //하좌우상 - final static int[] dr = {1, 0, 0, -1}; - final static int[] dc = {0, -1, 1, 0}; - - - - static int N; //세로 크기 - static int M; //가로 크기 - - static int[][] map; //숫자판 정보 - - static boolean[][] visited; //방문체크 - - static int max; //최댓값 - - 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 int[N+2][M+2]; - for(int i=1; i<=N; i++) { - st = new StringTokenizer(br.readLine()); - for(int j=1; j<=M; j++) { - map[i][j] = Integer.parseInt(st.nextToken()); - } - } - - - visited = new boolean[N+2][M+2]; - - - for(int i=1; i<=N; i++) { - for(int j=1; j<=M; j++) { - visited[i][j] = true; - dfs(i,j, map[i][j], 1); - visited[i][j] = false; - - //가운데 블록 기준 3개 블록이 붙어있는 테트로미노 탐색 - etc(i, j, map[i][j]); - } - } - - System.out.println(max); - } - - //가운데 블록 기준 3개 블록이 붙어있는 테트로미노 탐색 - private static void etc(int r, int c, int sum) { - - //(r,c) 기준 4방의 값을 모두 더함 - for(int d=0; d<4; d++) { - int nr = r+dr[d]; - int nc = c+dc[d]; - sum+= map[nr][nc]; - } - - //4방의 값을 하나씩 빼보면서 해당 값이 최댓값이라면 갱신 - for(int d=0; d<4; d++) { - int nr = r+dr[d]; - int nc = c+dc[d]; - max = Math.max(max, sum-map[nr][nc]); - } - } - - /** - * 블록하나를 선택하고 다음 블록 선택은 재귀호출로 넘김 - * @param r - * @param c - * @param sum //선택한 블록의 숫자 합 - * @param cnt //선택한 블록의 개수 - */ - private static void dfs(int r, int c, int sum, int cnt) { - - //step01. 4개의 블록 선택 완료 - if(cnt==4) { - //step 02. 선택한 블록 숫자의 합이 최댓값이라면 갱신 - max = Math.max(sum, max); - return; - } - - //윗 방향을 제외한 3방향으로 이동하며 블록 선택 - for(int d=0; d<3; d++) { - - int nr = r+dr[d]; - int nc = c+dc[d]; - - //경계를 벗어나거나 이미 방문했다면 다음 방향 - if(nr>N || nc<1 || nc>M || visited[nr][nc]) continue; - - visited[nr][nc] = true; - dfs(nr, nc, sum+map[nr][nc], cnt+1); - visited[nr][nc] = false; - } - - } - - - -} diff --git a/week16/Baekjoon2573.java b/week16/Baekjoon2573.java deleted file mode 100644 index ee7e1ab..0000000 --- a/week16/Baekjoon2573.java +++ /dev/null @@ -1,125 +0,0 @@ - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.StringTokenizer; - -/** - * - * 각 지점을 중심으로 dfs 아래, 왼쪽, 오른쪽 방향으로만 dfs 탐색 depth:4로 - * - 탐색 시 최대값을 발견한다면 갱신 - * 탐색한 지점은 방문 처리 - * - * - * - * 가운데 모양은 따로 탐색 필요 - * - * - * @author SSAFY - * - */ -public class Main_B_14500_테트로미노_연민호 { - - //하좌우상 - final static int[] dr = {1, 0, 0, -1}; - final static int[] dc = {0, -1, 1, 0}; - - - - static int N; //세로 크기 - static int M; //가로 크기 - - static int[][] map; //숫자판 정보 - - static boolean[][] visited; //방문체크 - - static int max; //최댓값 - - 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 int[N+2][M+2]; - for(int i=1; i<=N; i++) { - st = new StringTokenizer(br.readLine()); - for(int j=1; j<=M; j++) { - map[i][j] = Integer.parseInt(st.nextToken()); - } - } - - - visited = new boolean[N+2][M+2]; - - - for(int i=1; i<=N; i++) { - for(int j=1; j<=M; j++) { - visited[i][j] = true; - dfs(i,j, map[i][j], 1); - visited[i][j] = false; - - //가운데 블록 기준 3개 블록이 붙어있는 테트로미노 탐색 - etc(i, j, map[i][j]); - } - } - - System.out.println(max); - } - - //가운데 블록 기준 3개 블록이 붙어있는 테트로미노 탐색 - private static void etc(int r, int c, int sum) { - - //(r,c) 기준 4방의 값을 모두 더함 - for(int d=0; d<4; d++) { - int nr = r+dr[d]; - int nc = c+dc[d]; - sum+= map[nr][nc]; - } - - //4방의 값을 하나씩 빼보면서 해당 값이 최댓값이라면 갱신 - for(int d=0; d<4; d++) { - int nr = r+dr[d]; - int nc = c+dc[d]; - max = Math.max(max, sum-map[nr][nc]); - } - } - - /** - * 블록하나를 선택하고 다음 블록 선택은 재귀호출로 넘김 - * @param r - * @param c - * @param sum //선택한 블록의 숫자 합 - * @param cnt //선택한 블록의 개수 - */ - private static void dfs(int r, int c, int sum, int cnt) { - - //step01. 4개의 블록 선택 완료 - if(cnt==4) { - //step 02. 선택한 블록 숫자의 합이 최댓값이라면 갱신 - max = Math.max(sum, max); - return; - } - - //윗 방향을 제외한 3방향으로 이동하며 블록 선택 - for(int d=0; d<3; d++) { - - int nr = r+dr[d]; - int nc = c+dc[d]; - - //경계를 벗어나거나 이미 방문했다면 다음 방향 - if(nr>N || nc<1 || nc>M || visited[nr][nc]) continue; - - visited[nr][nc] = true; - dfs(nr, nc, sum+map[nr][nc], cnt+1); - visited[nr][nc] = false; - } - - } - - - -} diff --git a/week16/Baekjoon7662.java b/week16/Baekjoon7662.java deleted file mode 100644 index ee7e1ab..0000000 --- a/week16/Baekjoon7662.java +++ /dev/null @@ -1,125 +0,0 @@ - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.StringTokenizer; - -/** - * - * 각 지점을 중심으로 dfs 아래, 왼쪽, 오른쪽 방향으로만 dfs 탐색 depth:4로 - * - 탐색 시 최대값을 발견한다면 갱신 - * 탐색한 지점은 방문 처리 - * - * - * - * 가운데 모양은 따로 탐색 필요 - * - * - * @author SSAFY - * - */ -public class Main_B_14500_테트로미노_연민호 { - - //하좌우상 - final static int[] dr = {1, 0, 0, -1}; - final static int[] dc = {0, -1, 1, 0}; - - - - static int N; //세로 크기 - static int M; //가로 크기 - - static int[][] map; //숫자판 정보 - - static boolean[][] visited; //방문체크 - - static int max; //최댓값 - - 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 int[N+2][M+2]; - for(int i=1; i<=N; i++) { - st = new StringTokenizer(br.readLine()); - for(int j=1; j<=M; j++) { - map[i][j] = Integer.parseInt(st.nextToken()); - } - } - - - visited = new boolean[N+2][M+2]; - - - for(int i=1; i<=N; i++) { - for(int j=1; j<=M; j++) { - visited[i][j] = true; - dfs(i,j, map[i][j], 1); - visited[i][j] = false; - - //가운데 블록 기준 3개 블록이 붙어있는 테트로미노 탐색 - etc(i, j, map[i][j]); - } - } - - System.out.println(max); - } - - //가운데 블록 기준 3개 블록이 붙어있는 테트로미노 탐색 - private static void etc(int r, int c, int sum) { - - //(r,c) 기준 4방의 값을 모두 더함 - for(int d=0; d<4; d++) { - int nr = r+dr[d]; - int nc = c+dc[d]; - sum+= map[nr][nc]; - } - - //4방의 값을 하나씩 빼보면서 해당 값이 최댓값이라면 갱신 - for(int d=0; d<4; d++) { - int nr = r+dr[d]; - int nc = c+dc[d]; - max = Math.max(max, sum-map[nr][nc]); - } - } - - /** - * 블록하나를 선택하고 다음 블록 선택은 재귀호출로 넘김 - * @param r - * @param c - * @param sum //선택한 블록의 숫자 합 - * @param cnt //선택한 블록의 개수 - */ - private static void dfs(int r, int c, int sum, int cnt) { - - //step01. 4개의 블록 선택 완료 - if(cnt==4) { - //step 02. 선택한 블록 숫자의 합이 최댓값이라면 갱신 - max = Math.max(sum, max); - return; - } - - //윗 방향을 제외한 3방향으로 이동하며 블록 선택 - for(int d=0; d<3; d++) { - - int nr = r+dr[d]; - int nc = c+dc[d]; - - //경계를 벗어나거나 이미 방문했다면 다음 방향 - if(nr>N || nc<1 || nc>M || visited[nr][nc]) continue; - - visited[nr][nc] = true; - dfs(nr, nc, sum+map[nr][nc], cnt+1); - visited[nr][nc] = false; - } - - } - - - -} diff --git "a/week16/Baekjoon_16562_\354\271\234\352\265\254\353\271\204.java" "b/week16/Baekjoon_16562_\354\271\234\352\265\254\353\271\204.java" new file mode 100644 index 0000000..e3023cb --- /dev/null +++ "b/week16/Baekjoon_16562_\354\271\234\352\265\254\353\271\204.java" @@ -0,0 +1,72 @@ +import java.io.*; +import java.util.*; + +/** + * 시간: 88ms + * 메모리: 12404KB + */ +public class Baekjoon_16562_친구비 { + // Input Handler + static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + static StringBuilder sb = new StringBuilder(); + static StringTokenizer st; + // types + // constants + static final int SIZE = 10_000; + // variables + static int N, M, K; + static int[] A = new int[SIZE + 1]; + static int[] parents = new int[SIZE + 1]; + static int[] ranks = new int[SIZE + 1]; + + + static int getId(int u) { + if (u == parents[u]) return u; + return parents[u] = getId(parents[u]); + } + + static void merge(int u, int v) { + u = getId(u); + v = getId(v); + if (u == v) + return; + + if (ranks[u] < ranks[v]) { + int tmp = u; + u = v; + v = tmp; + } else if (ranks[u] == ranks[v]) { + ++ranks[u]; + } + parents[v] = u; + A[u] = Math.min(A[u], A[v]); + } + + public static void main(String[] args) throws IOException { + N = readInt(); + M = readInt(); + K = readInt(); + for (int i = 1; i <= N; ++i) A[i] = readInt(); + + for (int i = 1; i <= N; ++i) parents[i] = i; // 서로소 집합 초기화 + for (int i = 0; i < M; ++i) { + int u = readInt(), v = readInt(); + merge(u, v); + } + int sum = 0; + for (int i = 1; i <= N; ++i) { + if (i == parents[i]) { + sum += A[i]; + } + } + if (sum <= K) System.out.println(sum); + else System.out.println("Oh no"); + } + + static int readInt() throws IOException { + int c, n = 0; + while((c = System.in.read()) >= 0x30) n = (n << 3) + (n << 1) + (c & 0x0F); + if(c == '\r') System.in.read(); + return n; + } +} \ No newline at end of file diff --git "a/week16/Baekjoon_1916_\354\265\234\354\206\214\353\271\204\354\232\251\352\265\254\355\225\230\352\270\260.java" "b/week16/Baekjoon_1916_\354\265\234\354\206\214\353\271\204\354\232\251\352\265\254\355\225\230\352\270\260.java" index d37fb69..429f9df 100644 --- "a/week16/Baekjoon_1916_\354\265\234\354\206\214\353\271\204\354\232\251\352\265\254\355\225\230\352\270\260.java" +++ "b/week16/Baekjoon_1916_\354\265\234\354\206\214\353\271\204\354\232\251\352\265\254\355\225\230\352\270\260.java" @@ -1,70 +1,88 @@ -import java.util.*; -import java.io.*; - -/** - * 250612 - * Java8 | 시간: 328 ms, 메모리: 24,996 KB - */ - -public class Baekjoon_1916_최소비용구하기 { - static class Node implements Comparable{ - int v, cost; - Node(int v, int cost){ - this.v = v; - this.cost = cost; - } - - @Override - public int compareTo(Node o) { - return Integer.compare(this.cost, o.cost); - } - } - - public static void main(String[] args) throws IOException { - int N = readInt(); - int M = readInt(); - - ArrayList> map = new ArrayList<>(); - for (int i=0;i<=N;i++) map.add(new ArrayList<>()); - - for (int i=0;i> map){ - int[] dist = new int[N+1]; - Arrays.fill(dist, Integer.MAX_VALUE); - dist[start] = 0; - - PriorityQueue pq = new PriorityQueue<>(); - pq.offer(new Node(start, 0)); - - while(!pq.isEmpty()){ - Node c = pq.poll(); - if (dist[c.v] < c.cost) continue; - - for (Node nextPoint:map.get(c.v)){ - int nc = c.cost + nextPoint.cost; - if (dist[nextPoint.v]>nc){ - dist[nextPoint.v] = nc; - pq.offer(new Node(nextPoint.v, nc)); - } - } - } - return dist[end]; - } - - private static final StreamTokenizer st = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in))); - private static int readInt() throws IOException{ - st.nextToken(); - return (int) st.nval; - } -} +import java.io.*; +import java.util.*; + +/** + * 시간: 184ms + * 메모리: 20,660KB + */ +public class Baekjoon_1916_최소비용구하기 { + // Input Handler + static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + static StringBuilder sb = new StringBuilder(); + + static class Node implements Comparable { + int vertex, weight; + + Node() { } + Node(int vertex, int weight) { + this.vertex = vertex; + this.weight = weight; + } + + @Override + public int compareTo(Node other) { + return this.weight - other.weight; + } + } + + static final int MAX_N = 1_000; + static final int MAX_W = 100_000; + static final int INF = MAX_N * MAX_W; + + static int N, M, S, T; + static List[] adj = new List[MAX_N]; + static int[] minDist = new int[MAX_N]; + + static void solution() { + Arrays.fill(minDist, 0, N, INF); + + PriorityQueue pq = new PriorityQueue(); + pq.offer(new Node(S, 0)); + minDist[S] = 0; + + while (!pq.isEmpty()) { + Node node = pq.poll(); + int u = node.vertex, w = node.weight; + if (u == T) + break; + + for (Node next : adj[u]) { + int v = next.vertex, edge = next.weight; + if (w + edge < minDist[v]) { + minDist[v] = w + edge; + pq.offer(new Node(v, minDist[v])); + } + } + } + } + + public static void main(String[] args) throws IOException { + // Input + N = readInt(); + for (int i = 0; i < N; ++i) + adj[i] = new ArrayList(); + + M = readInt(); + for (int i = 0; i < M; ++i) { + int u = readInt() - 1; + int v = readInt() - 1; + int w = readInt(); + adj[u].add(new Node(v, w)); + } + + S = readInt() - 1; + T = readInt() - 1; + + solution(); + + // Output + System.out.print(minDist[T]); + } + + static int readInt() throws IOException { + int c, n = 0; + while ((c = System.in.read()) >= 0x30) n = (n << 3) + (n << 1) + (c & 0x0F); + if (c == '\r') System.in.read(); + return n; + } +} diff --git "a/week16/Baekjoon_2096_\353\202\264\353\240\244\352\260\200\352\270\260.java" "b/week16/Baekjoon_2096_\353\202\264\353\240\244\352\260\200\352\270\260.java" index 36184b3..672a485 100644 --- "a/week16/Baekjoon_2096_\353\202\264\353\240\244\352\260\200\352\270\260.java" +++ "b/week16/Baekjoon_2096_\353\202\264\353\240\244\352\260\200\352\270\260.java" @@ -1,44 +1,53 @@ -import java.io.*; - -/** - * 250612 - * Java8 | 실행시간: 196 ms, 메모리: 17412 KB - */ - -public class Baekjoon_2096_내려가기 { - - public static void main(String[] args) throws IOException{ - - int N = readInt(); - int[][] maxDp = new int[2][3]; - int[][] minDp = new int[2][3]; - for (int i=0;i<3;i++) maxDp[0][i] = minDp[0][i] = readInt(); - - for (int i=1;i= 0; --y) { + maxMat[y][0] += Math.max(maxMat[y + 1][0], maxMat[y + 1][1]); + minMat[y][0] += Math.min(minMat[y + 1][0], minMat[y + 1][1]); + + maxMat[y][1] += Math.max(Math.max(maxMat[y + 1][0], maxMat[y + 1][1]), maxMat[y + 1][2]); + minMat[y][1] += Math.min(Math.min(minMat[y + 1][0], minMat[y + 1][1]), minMat[y + 1][2]); + + maxMat[y][2] += Math.max(maxMat[y + 1][1], maxMat[y + 1][2]); + minMat[y][2] += Math.min(minMat[y + 1][1], minMat[y + 1][2]); + } + for(int x = 0; x < WIDTH; ++x) { + max = Math.max(max, maxMat[0][x]); + min = Math.min(min, minMat[0][x]); + } + + sb.append(max).append(" ").append(min); + System.out.print(sb); + } + + static int readInt() throws IOException { + int c, n = 0; + while((c = System.in.read()) >= 0x30) n = (n << 3) + (n << 1) + (c & 0x0F); + if(c == '\r') System.in.read(); + return n; + } +} diff --git "a/week16/Baekjoon_2573_\353\271\231\354\202\260.java" "b/week16/Baekjoon_2573_\353\271\231\354\202\260.java" index 9b9ae08..fd2b516 100644 --- "a/week16/Baekjoon_2573_\353\271\231\354\202\260.java" +++ "b/week16/Baekjoon_2573_\353\271\231\354\202\260.java" @@ -1,111 +1,131 @@ -/** - * 250611 - * Java8 | 시간: 388ms, 메모리 : 123,540KB - */ -import java.util.*; import java.io.*; +import java.util.*; -public class Baekjoon_2573_빙산 { - private static int N, M; - private static boolean[][] isIceberg, isVisited; - private static final int[] dx = {0, 0, -1, 1}; - private static final int[] dy = {-1, 1, 0, 0}; - - private static class Cor{ - int x, y, height; - Cor(int x, int y, int height){ - this.x = x; - this.y = y; - this.height = height; - } - } +/** + * 시간: 380ms + * 메모리: 71,212KB + */ +public class Baekjoon_2573_빙산 { + static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + static StringBuilder sb = new StringBuilder(); + + static final int[] dy = {0,0,1,-1}; + static final int[] dx = {1,-1,0,0}; + + static int N, M; + static int[][] mat; + static int[][] melts; + + + static boolean inRange(int y, int x) { + return 0 <= y && y < N && 0 <= x && x < M; + } + + static void floodFill(int ay, int ax, boolean[][] isVisisted) { + Deque q = new ArrayDeque<>(); + + q.offerLast(new int[] {ax, ay}); + isVisisted[ay][ax] = true; + while(!q.isEmpty()) { + int[] node = q.pollFirst(); + int y = node[1]; + int x = node[0]; + + for(int d = 0; d < dy.length; ++d) { + int ny = y + dy[d]; + int nx = x + dx[d]; + if(inRange(ny, nx) && !isVisisted[ny][nx] && mat[y][x] > 0) { + q.offerLast(new int[] {nx, ny}); + isVisisted[ny][nx] = true; + } + } + } + } + + static int getCount() { + boolean[][] isVisisted = new boolean[N][M]; + + int cnt = 0; + for(int y = 0; y < N; ++y) { + for(int x = 0; x < M; ++x) { + if(isVisisted[y][x] || mat[y][x] <= 0) continue; + floodFill(y, x, isVisisted); + ++cnt; + } + } + return cnt; + } + + static void update() { + Deque q = new ArrayDeque<>(); + + for(int y = 0; y < N; ++y) { + for(int x = 0; x < M; ++x) { + if(mat[y][x] <= 0) continue; + + if((mat[y][x] -= melts[y][x]) <= 0) { + q.offerLast(new int[] {x, y}); + } + } + } + + while(!q.isEmpty()) { + int[] node = q.pollFirst(); + int y = node[1]; + int x = node[0]; + + for(int d = 0; d < dy.length; ++d) { + int ny = y + dy[d]; + int nx = x + dx[d]; + if(inRange(ny, nx)) { + ++melts[ny][nx]; + } + } + } + } + public static void main(String[] args) throws IOException { - N = readInt(); - M = readInt(); - - Queue icebergQueue = new ArrayDeque<>(); - - for (int i=0;i0) icebergQueue.offer(new Cor(i, j, height)); - } - - int year = 0; - while(!icebergQueue.isEmpty()){ - isIceberg = new boolean[N][M]; - for (Cor c:icebergQueue) isIceberg[c.x][c.y] = true; - - if (isSeparated(icebergQueue)){ - System.out.print(year); - return; - } - - simulation(icebergQueue); - year++; - } - - System.out.print(0); - } - - // 녹이기 - private static void simulation(Queue icebergQueue){ - int size = icebergQueue.size(); - - while(size-->0){ - Cor c = icebergQueue.poll(); - int water = 0; - for (int idx=0; idx<4; idx++){ - int nx = c.x + dx[idx]; - int ny = c.y + dy[idx]; - if (nx<0||nx>=N||ny<0||ny>=M||isIceberg[nx][ny]) continue; - water++; - } - - int newHeight = Math.max(c.height-water, 0); - if (newHeight>0) { - icebergQueue.offer(new Cor(c.x, c.y, newHeight)); - } - } - } - - // 두 덩어리 이상으로 분리되었는지 확인 - private static boolean isSeparated(Queue icebergQueue){ - - isVisited = new boolean[N][M]; - int ct = 0; - - for (Cor c : icebergQueue) { - if (!isVisited[c.x][c.y]) { - bfs(c.x, c.y); - if (++ct>=2) return true; - } - } - return false; + N = readInt(); + M = readInt(); + mat = new int[N][M]; + melts = new int[N][M]; + + for(int y = 0; y < N; ++y) { + for(int x = 0; x < M; ++x) { + mat[y][x] = readInt(); + } + } + for(int y = 0; y < N; ++y) { + for(int x = 0; x < M; ++x) { + for(int d = 0; d < dy.length; ++d) { + int ny = y + dy[d]; + int nx = x + dx[d]; + if(inRange(ny, nx) && mat[ny][nx] == 0) { + ++melts[y][x]; + } + } + } + } + + int t = 0; + while(true) { + int cnt = getCount(); + if(cnt == 1) { + update(); + t++; + continue; + } + if(cnt == 0) System.out.print(0); + else System.out.print(t); + return; + } } - - // 영역 구하기 - private static void bfs(int x, int y){ - Queue q = new ArrayDeque<>(); - q.offer(new Cor(x, y, 0)); - isVisited[x][y] = true; - - while(!q.isEmpty()){ - Cor c = q.poll(); - for (int idx=0; idx<4; idx++){ - int nx = c.x + dx[idx]; - int ny = c.y + dy[idx]; - if (nx<0||nx>=N||ny<0||ny>=M) continue; - if (isVisited[nx][ny]||!isIceberg[nx][ny]) continue; - isVisited[nx][ny] = true; - q.offer(new Cor(nx, ny, 0)); - } - } - } - - private static StreamTokenizer st = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in))); - private static int readInt() throws IOException{ - st.nextToken(); - return (int) st.nval; + + static int readInt() throws IOException { + int c, n = 0; + while((c = System.in.read()) >= 0x30) n = (n << 3) + (n << 1) + (c & 0x0F); + if(c == '\r') System.in.read(); + return n; } } diff --git "a/week16/Baekjoon_7662_\354\235\264\354\244\221\354\232\260\354\204\240\354\210\234\354\234\204\355\201\220.java" "b/week16/Baekjoon_7662_\354\235\264\354\244\221\354\232\260\354\204\240\354\210\234\354\234\204\355\201\220.java" new file mode 100644 index 0000000..f317c96 --- /dev/null +++ "b/week16/Baekjoon_7662_\354\235\264\354\244\221\354\232\260\354\204\240\354\210\234\354\234\204\355\201\220.java" @@ -0,0 +1,54 @@ +import java.io.*; +import java.util.*; + + +/** + * 시간: 2,364ms + * 메모리: 439,744KB + */ +public class Baekjoon_7662_이중우선순위큐 { + // IO + static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + static StringBuilder sb = new StringBuilder(); + static StringTokenizer st = null; + // types + // constants + // variables + static int T; + static int N; + static TreeMap q = new TreeMap(); + + public static void main(String[] args) throws IOException { + T = Integer.parseInt(br.readLine()); + while(T-- > 0) { + q.clear(); + N = Integer.parseInt(br.readLine()); + while(N-- > 0) { + st = new StringTokenizer(br.readLine()); + String cmd = st.nextToken(); + int val = Integer.parseInt(st.nextToken()); + + switch(cmd) { + case "I": { + q.put(val, q.getOrDefault(val, 0)+1); + break; + } + case "D": { + if(q.isEmpty()) break; + + if(val == 1) val = q.lastKey(); + else val = q.firstKey(); + + int cnt = q.get(val); + if(cnt == 1) q.remove(val); + else if(cnt > 1) q.put(val, q.get(val)-1); + break; + } + } + } + if(q.isEmpty()) sb.append("EMPTY\n"); + else sb.append(q.lastKey()).append(" ").append(q.firstKey()).append("\n"); + } + System.out.print(sb); + } +} \ No newline at end of file diff --git "a/week17/Baekjoon_1516_\352\262\214\354\236\204\352\260\234\353\260\234.java" "b/week17/Baekjoon_1516_\352\262\214\354\236\204\352\260\234\353\260\234.java" new file mode 100644 index 0000000..76e05d5 --- /dev/null +++ "b/week17/Baekjoon_1516_\352\262\214\354\236\204\352\260\234\353\260\234.java" @@ -0,0 +1,69 @@ +import java.io.*; +import java.util.*; + + +/** + * 시간: 108ms + * 메모리: 14,340KB + */ +public class Baekjoon_1516_게임개발 { + // IO + static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + static StringBuilder sb = new StringBuilder(); + static StringTokenizer st = null; + // variables + static int N; + static int[] costs; + static List[] adj; + static boolean[] isVisited; + static Deque stk = new ArrayDeque<>(); + + + static void dfs(int u) { + isVisited[u] = true; + int delay = 0; + for(int v : adj[u]) { + if(isVisited[v]) continue; + dfs(v); + } + for(int v : adj[u]) delay = Math.max(delay, costs[v]); + + stk.offerLast(u); + costs[u] += delay; + } + + public static void main(String[] args) throws IOException { + // input + N = readInt(); + costs = new int[N + 1]; + adj = new List[N + 1]; + isVisited = new boolean[N + 1]; + + for(int i = 1; i <= N; ++i) adj[i] = new ArrayList<>(); + for(int u = 1; u <= N; ++u) { + costs[u] = readInt(); + int v; + while((v = readInt()) > 0) adj[u].add(v); + } + // solution + for(int u = 1; u <= N; ++u) { + if(isVisited[u]) continue; + dfs(u); + } + // output + for(int i = 1; i <= N; ++i) { + sb.append(costs[i]).append('\n'); + } + System.out.print(sb); + } + static int readInt() throws IOException { + int c, n = System.in.read() & 0x0F, s = 1; + if(n == ('-' & 0x0F)) { + n = 0; + s = -1; + } + while((c = System.in.read()) >= 0x30) n = (n << 3) + (n << 1) + (c & 0x0F); + if(c == '\r') System.in.read(); + return n*s; + } +} \ No newline at end of file diff --git "a/week17/Baekjoon_17182_\354\232\260\354\243\274\355\203\220\354\202\254\354\204\240.java" "b/week17/Baekjoon_17182_\354\232\260\354\243\274\355\203\220\354\202\254\354\204\240.java" new file mode 100644 index 0000000..c368cb1 --- /dev/null +++ "b/week17/Baekjoon_17182_\354\232\260\354\243\274\355\203\220\354\202\254\354\204\240.java" @@ -0,0 +1,62 @@ +import java.io.*; +import java.util.*; + + +/** + * 시간: 104ms + * 메모리: 11,752KB + */ +public class Baekjoon_17182_우주탐사선 { + // IO + static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + static StringBuilder sb = new StringBuilder(); + // variables + static int N, K; + static int[][] minDist; + static int minTime = Integer.MAX_VALUE; + + static void floyd() { + for(int k = 0; k < N; ++k) { + for(int i = 0; i < N; ++i) { + for(int j = 0; j < N; ++j) { + if(minDist[i][j] > minDist[i][k] + minDist[k][j]) { + minDist[i][j] = minDist[i][k] + minDist[k][j]; + } + } + } + } + } + + static void minTravel(int from, int elapsed, int isVisited) { + if(isVisited == ((0x01 << N) - 1)) { + minTime = Math.min(minTime, elapsed); + return; + } + for(int to = 0; to < N; ++to) { + if(((isVisited >> to) & 0x01) != 0) continue; + if(elapsed + minDist[from][to] >= minTime) continue; + minTravel(to, elapsed + minDist[from][to], isVisited | (0x01 << to)); + } + } + + public static void main(String[] args) throws IOException { + N = readInt(); + K = readInt(); + minDist = new int[N][N]; + for(int i = 0; i < N; ++i) { + for(int j = 0; j < N; ++j) { + minDist[i][j] = readInt(); + } + } + floyd(); + minTravel(K, 0, 0x01 << K); + System.out.print(minTime); + } + + static int readInt() throws IOException { + int c, n = 0; + while((c = System.in.read()) >= 0x30) n = (n << 3) + (n << 1) + (c & 0x0F); + if(c == '\r') System.in.read(); + return n; + } +} \ No newline at end of file diff --git "a/week17/Baekjoon_21939_\353\254\270\354\240\234\354\266\224\354\262\234\354\213\234\354\212\244\355\205\234Version1.java" "b/week17/Baekjoon_21939_\353\254\270\354\240\234\354\266\224\354\262\234\354\213\234\354\212\244\355\205\234Version1.java" new file mode 100644 index 0000000..0badbd5 --- /dev/null +++ "b/week17/Baekjoon_21939_\353\254\270\354\240\234\354\266\224\354\262\234\354\213\234\354\212\244\355\205\234Version1.java" @@ -0,0 +1,96 @@ +import java.io.*; +import java.util.*; + + +/** + * 시간: 248ms + * 메모리: 26,456KB + */ +public class Baekjoon_21939_문제추천시스템Version1 { + // IO + static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + static StringBuilder sb = new StringBuilder(); + static StringTokenizer st = null; + // tpyes + static class Problem implements Comparable { + Problem() {} + Problem(int P, int L) { this.P = P; this.L = L; } + + int P, L; + + @Override + public int compareTo(Problem o) { + if(this.L != o.L) return this.L - o.L; + return this.P - o.P; + } + } + // variables + static int N, M; + static PriorityQueue minHeap = new PriorityQueue<>(); + static PriorityQueue maxHeap = new PriorityQueue<>(Collections.reverseOrder()); + static Map pool = new HashMap<>(); + + + public static void main(String[] args) throws IOException { + N = readInt(); + for(int i = 0; i < N; ++i) { + int P = readInt(); + int L = readInt(); + + Problem problem = new Problem(P, L); + minHeap.add(problem); + maxHeap.add(problem); + pool.put(P, problem); + } + + M = readInt(); + while(M-- > 0) { + int cmd = getWordFirst(); + if(cmd == 'r') { + int x = readInt(); + if(x > 0) { + while(pool.getOrDefault(maxHeap.peek().P, null) != maxHeap.peek()) { + maxHeap.poll(); + } + sb.append(maxHeap.peek().P).append("\n"); + } else { + while(pool.getOrDefault(minHeap.peek().P, null) != minHeap.peek()) { + minHeap.poll(); + } + sb.append(minHeap.peek().P).append("\n"); + } + } else { + if(cmd == 'a') { + int P = readInt(); + int L = readInt(); + + Problem problem = new Problem(P, L); + minHeap.add(problem); + maxHeap.add(problem); + pool.put(P, problem); + } else { + int P = readInt(); + pool.remove(P); + } + } + } + System.out.print(sb); + } + + static int getWordFirst() throws IOException { + int n = System.in.read(); + while(System.in.read() > 0x20) continue; + return n; + } + + static int readInt() throws IOException { + int c, n = System.in.read() & 0x0F, s = 1; + if(n == ('-' & 0x0F)) { + n = 0; + s = -1; + } + while((c = System.in.read()) >= 0x30) n = (n << 3) + (n << 1) + (c & 0x0F); + if(c == '\r') System.in.read(); + return n*s; + } +} \ No newline at end of file diff --git "a/week17/Baekjoon_2357_\354\265\234\354\206\237\352\260\222\352\263\274\354\265\234\353\214\223\352\260\222.java" "b/week17/Baekjoon_2357_\354\265\234\354\206\237\352\260\222\352\263\274\354\265\234\353\214\223\352\260\222.java" new file mode 100644 index 0000000..cfe7e60 --- /dev/null +++ "b/week17/Baekjoon_2357_\354\265\234\354\206\237\352\260\222\352\263\274\354\265\234\353\214\223\352\260\222.java" @@ -0,0 +1,63 @@ +import java.io.*; +import java.util.*; + + +/** + * 시간: 420ms + * 메모리: 149,580KB + */ +public class Baekjoon_2357_최솟값과최댓값 { + // Input Handler + static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + static StringBuilder sb = new StringBuilder(); + static StringTokenizer st = null; + // types + // constants + static int SIZE = 100_000; + // variables + static int N, M; + static int[] arr = new int[SIZE]; + static int[][] segment = new int[SIZE << 2][2]; + + + static int[] initSegment(int segmentL, int segmentR, int index) { + if(segmentL == segmentR) return segment[index] = new int[] {arr[segmentL], arr[segmentR]}; + int mid = (segmentL + segmentR) >> 1; + int[] lhs = initSegment(segmentL, mid, index * 2 + 1); + int[] rhs = initSegment(mid + 1, segmentR, index * 2 + 2); + return segment[index] = new int[] { Math.min(lhs[0], rhs[0]), Math.max(lhs[1], rhs[1]) }; + } + + static int[] querySegment(int queryL, int queryR, int segmentL, int segmentR, int index) { + if(segmentR < queryL || queryR < segmentL) return new int[] {Integer.MAX_VALUE, Integer.MIN_VALUE}; + if(queryL <= segmentL && segmentR <= queryR) return segment[index]; + + int mid = (segmentL + segmentR) >> 1; + int[] lhs = querySegment(queryL, queryR, segmentL, mid, index * 2 + 1); + int[] rhs = querySegment(queryL, queryR, mid + 1, segmentR, index * 2 + 2); + return new int[] { Math.min(lhs[0], rhs[0]), Math.max(lhs[1], rhs[1]) }; + } + + + public static void main(String[] args) throws IOException { + N = readInt(); + M = readInt(); + for(int i = 0; i < N; ++i) arr[i] = readInt(); + + initSegment(0, N - 1, 0); + for(int i = 0; i < M; ++i) { + int a = readInt(), b = readInt(); + int[] ans = querySegment(a - 1, b - 1, 0, N - 1, 0); + sb.append(ans[0]).append(" ").append(ans[1]).append("\n"); + } + System.out.print(sb); + } + + // 정수 입력 + static int readInt() throws IOException { + int c, n = 0; + while((c = System.in.read()) >= 0x30) n = (n << 3) + (n << 1) + (c & 0x0F); + if(c == ('\r' & 0x0F)) System.in.read(); + return n; + } +} \ No newline at end of file diff --git "a/week17/Baekjoon_2812_\355\201\254\352\262\214\353\247\214\353\223\244\352\270\260.java" "b/week17/Baekjoon_2812_\355\201\254\352\262\214\353\247\214\353\223\244\352\270\260.java" new file mode 100644 index 0000000..9a0e8e5 --- /dev/null +++ "b/week17/Baekjoon_2812_\355\201\254\352\262\214\353\247\214\353\223\244\352\270\260.java" @@ -0,0 +1,40 @@ +import java.io.*; +import java.util.*; + + +/** + * 시간: 240ms + * 메모리: 41,540KB + */ +public class Baekjoon_2812_크게만들기 { + // IO + static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + static StringBuilder sb = new StringBuilder(); + // variables + static int N, K; + + + public static void main(String[] args) throws IOException { + N = readInt(); + K = readInt(); + + Deque stk = new ArrayDeque(); + for(char digit : br.readLine().toCharArray()) { + while(K > 0 && (!stk.isEmpty() && stk.peekLast() < digit)) { + stk.pollLast(); + --K; + } + stk.offerLast(digit); + } + + for(int i = 0, n = stk.size() - K; i < n; ++i) sb.append(stk.pollFirst()); + System.out.print(sb); + } + + static int readInt() throws IOException { + int c, n = 0; + while((c = System.in.read()) >= 0x30) n = (n << 3) + (n << 1) + (c & 0x0F); + if(c == '\r') System.in.read(); + return n; + } +} \ No newline at end of file diff --git "a/week18/Baekjoon_17619_\352\260\234\352\265\254\353\246\254\354\240\220\355\224\204.java" "b/week18/Baekjoon_17619_\352\260\234\352\265\254\353\246\254\354\240\220\355\224\204.java" new file mode 100644 index 0000000..431af03 --- /dev/null +++ "b/week18/Baekjoon_17619_\352\260\234\352\265\254\353\246\254\354\240\220\355\224\204.java" @@ -0,0 +1,72 @@ +import java.io.*; +import java.util.*; + +/* + * 시간: 296ms + * 메모리: 19568KB + */ +public class Baekjoon_17619_개구리점프 { + // Input Handler + static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + static StringBuilder sb = new StringBuilder(); + static StringTokenizer st = null; + // types + static class Log implements Comparable { + int no, x1, x2; + + Log() { } + Log(int no, int x1, int x2) { + this.no = no; + this.x1 = x1; + this.x2 = x2; + } + + @Override + public int compareTo(Log other) { + return this.x1 - other.x1; + } + } + // constants + // variables + static int N, Q; + static PriorityQueue pq = new PriorityQueue<>(); + static int[] ids; + + + public static void main(String[] args) throws IOException { + N = readInt(); + Q = readInt(); + + ids = new int[N + 1]; + for(int i = 1; i <= N; ++i) { + ids[i] = i; + pq.offer(new Log(i, readInt(), readInt())); readInt(); + } + + int lastId = -1; + int lastPos = -1; + while(!pq.isEmpty()) { + Log log = pq.poll(); + + if(lastPos < log.x1) { // 수직방향으로 이동할 수 없다면 새로운 그룹을 만듦 + lastId = ids[log.no]; + } else { // 수직방향으로 이동할 수 있으므로 같은 그룹으로 등록 + ids[log.no] = lastId; + } + lastPos = Math.max(lastPos, log.x2); + } + + while(Q-- > 0) { + int from = readInt(), to = readInt(); + sb.append(ids[from] == ids[to] ? 1 : 0).append("\n"); + } + System.out.print(sb); + } + + static int readInt() throws IOException { + int c, n = 0; + while((c = System.in.read()) >= 0x30) n = (n << 3) + (n << 1) + (c & 0x0F); + if(c == '\r') System.in.read(); + return n; + } +} \ No newline at end of file diff --git "a/week18/Baekjoon_2011_\354\225\224\355\230\270\354\275\224\353\223\234.java" "b/week18/Baekjoon_2011_\354\225\224\355\230\270\354\275\224\353\223\234.java" new file mode 100644 index 0000000..910542a --- /dev/null +++ "b/week18/Baekjoon_2011_\354\225\224\355\230\270\354\275\224\353\223\234.java" @@ -0,0 +1,44 @@ +import java.io.*; +import java.util.*; +import java.util.function.BiFunction; + +/* + * https://www.acmicpc.net/problem/2011 + * 시간: 64ms + * 메모리:11520KB + */ +public class Baekjoon_2011_암호코드 { + // Input Handler + static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + static StringBuilder sb = new StringBuilder(); + static StringTokenizer st = null; + // types + // constants + static final int MOD = 1_000_000; + // variables + static char[] password; + + static int solution() { + if(password[0] == '0') return 0; + + int one = 1, two = 0; + for(int i = 1 ; i < password.length; ++i) { + int prevDigit = password[i-1] & 0x0F; + int curDigit = password[i] & 0x0F; + if(prevDigit == 0 && curDigit == 0) return 0; + + int nextOne = curDigit != 0 ? one + two : 0; + int nextTwo = prevDigit != 0 && prevDigit * 10 + curDigit <= 26 ? one : 0; + + one = nextOne % MOD; + two = nextTwo; + } + return (one + two) % MOD; + } + + public static void main(String[] args) throws IOException { + password = br.readLine().toCharArray(); + System.out.println(solution()); + + } +} \ No newline at end of file diff --git "a/week18/Baekjoon_20159_\353\217\231\354\236\221\352\267\270\353\247\214\353\260\221\354\236\245\353\271\274\352\270\260\353\203\220.java" "b/week18/Baekjoon_20159_\353\217\231\354\236\221\352\267\270\353\247\214\353\260\221\354\236\245\353\271\274\352\270\260\353\203\220.java" new file mode 100644 index 0000000..c302623 --- /dev/null +++ "b/week18/Baekjoon_20159_\353\217\231\354\236\221\352\267\270\353\247\214\353\260\221\354\236\245\353\271\274\352\270\260\353\203\220.java" @@ -0,0 +1,54 @@ +import java.io.*; +import java.util.*; +import java.util.function.BiFunction; + +/** + * https://www.acmicpc.net/problem/20159 + * 시간: 100ms + * 메모리: 13296KB + */ +public class Baekjoon_20159_동작그만밑장빼기냐 { + // Input Handler + static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + static StringBuilder sb = new StringBuilder(); + static StringTokenizer st = null; + // types + // constants + // variables + static int N; + static int[] X; + static int[] leftSum, rightSum; + + public static void main(String[] args) throws IOException { + N = readInt(); + X = new int[N]; + for(int i = 0; i < N; ++i) X[i] = readInt(); + + leftSum = new int[N+1]; // [i]: Sum(X[j % 2 == 0 && j < i]) + rightSum = new int[N+1]; // [i]: Sum(X[j % 2 == 1 && j >= N - i]) + + leftSum[0] = 0; + for(int i = 2; i <= N; i += 2) { + leftSum[i - 1] = leftSum[i] = leftSum[i - 2] + X[i - 2]; + } + rightSum[0] = 0; + for(int i = 2; i <= N; i += 2) { + rightSum[i - 1] = rightSum[i] = rightSum[i - 2] + X[N - i + 1]; + } + + int max = Integer.MIN_VALUE; + for(int i = 0; i <= N; ++i) { + int sum = leftSum[i] + rightSum[N - i]; + if(i % 2 == 1) sum -= X[N - 1]; + max = Math.max(max, sum); + } + System.out.print(max); + } + + static int readInt() throws IOException { + int c, n = 0; + while((c = System.in.read()) >= 0x30) n = (n << 3) + (n << 1) + (c & 0x0F); + if(c == '\r') System.in.read(); + return n; + } +} \ No newline at end of file diff --git "a/week18/Baekjoon_2170_\354\204\240\352\270\213\352\270\260.java" "b/week18/Baekjoon_2170_\354\204\240\352\270\213\352\270\260.java" new file mode 100644 index 0000000..7edcaf5 --- /dev/null +++ "b/week18/Baekjoon_2170_\354\204\240\352\270\213\352\270\260.java" @@ -0,0 +1,70 @@ +import java.io.*; +import java.util.*; + +/* + * https://www.acmicpc.net/problem/2170 + * 시간: 1032ms + * 메모리: 49316KB + */ +public class Baekjoon_2170_선긋기 { + // Input Handler + static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + static StringBuilder sb = new StringBuilder(); + static StringTokenizer st = null; + // types + static class Line implements Comparable { + int x, y; + + Line() { } + Line(int x, int y) { + this.x = x; + this.y = y; + } + + @Override + public int compareTo(Line other) { + return this.x - other.x; + } + } + // constants + // variables + static int N, Q; + static PriorityQueue pq = new PriorityQueue<>(); + static int[] ids; + + + public static void main(String[] args) throws IOException { + N = readInt(); + + for(int i = 0; i < N; ++i) { + pq.offer(new Line(readInt(), readInt())); + } + + int sum = 0; + int lastPos = Integer.MIN_VALUE; + while(!pq.isEmpty()) { + Line line = pq.poll(); + + if(lastPos < line.x) { // 선이 이어지지지 않음 + sum += line.y - line.x; + } else if(line.y > lastPos){ // 선이 이어졌고 길이가 연장됨 + sum += line.y - lastPos; + } + lastPos = Math.max(lastPos, line.y); + } + + + System.out.print(sum); + } + + static int readInt() throws IOException { + int c, n = System.in.read() & 0x0F, s = 1; + if(n == ('-' & 0x0F)) { + s = -1; + n = 0; + } + while((c = System.in.read()) >= 0x30) n = (n << 3) + (n << 1) + (c & 0x0F); + if(c == '\r') System.in.read(); + return n * s; + } +} \ No newline at end of file diff --git "a/week18/Baekjoon_9466_\355\205\200\355\224\204\353\241\234\354\240\235\355\212\270.java" "b/week18/Baekjoon_9466_\355\205\200\355\224\204\353\241\234\354\240\235\355\212\270.java" new file mode 100644 index 0000000..51704f2 --- /dev/null +++ "b/week18/Baekjoon_9466_\355\205\200\355\224\204\353\241\234\354\240\235\355\212\270.java" @@ -0,0 +1,65 @@ +import java.io.*; +import java.util.*; + +/* + * 시간: 776ms + * 메모리: 51100KB + */ +public class Baekjoon_9466_텀프로젝트 { + // Input Handler + static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + static StringBuilder sb = new StringBuilder(); + static StringTokenizer st = null; + // types + // constants + // variables + static int N; + static int[] S; + static int[] isVisited; // unvisited: 0, visited-in: 1, visited-out: 2 + static int ans; + + static int dfs(int u) { + if(isVisited[u] == 1) { // 순환 발견 + return u; + } + + if(isVisited[S[u]] == 2) { + isVisited[u] = 2; + return -1; + } + + isVisited[u] = 1; + int ret = dfs(S[u]); + if(ret >= 0) --ans; + isVisited[u] = 2; + return u != ret ? ret : -1; + } + + static int solution() { + ans = N; + for(int u = 0; u < N; ++u) { + if(isVisited[u] == 0) dfs(u); + } + return ans; + } + + public static void main(String[] args) throws IOException { + int T = readInt(); + while(T-- > 0) { + N = readInt(); + S = new int[N]; + isVisited = new int[N]; + + for(int i = 0; i < N; ++i) S[i] = readInt() - 1; + sb.append(solution()).append('\n'); + } + System.out.print(sb); + } + + static int readInt() throws IOException { + int c, n = 0; + while((c = System.in.read()) >= 0x30) n = (n << 3) + (n << 1) + (c & 0x0F); + if(c == '\r') System.in.read(); + return n; + } +} \ No newline at end of file diff --git "a/week19/Baekjoon_1083_\354\206\214\355\212\270.java" "b/week19/Baekjoon_1083_\354\206\214\355\212\270.java" new file mode 100644 index 0000000..74d04f9 --- /dev/null +++ "b/week19/Baekjoon_1083_\354\206\214\355\212\270.java" @@ -0,0 +1,58 @@ +import java.io.*; +import java.util.*; + +/** + * 시간: 68ms + * 메모리: 11524KB + */ +public class Baekjoon_1083_소트 { + // Input Handler + static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + static StringBuilder sb = new StringBuilder(); + static StringTokenizer st = null; + // types + // constants + // variables + static int N, S; + static int[] A; + + static void solution() { + for(int i = 0; i < N && S > 0; ++i) { + + int tgt = i; + for(int j = i+1; j < N && j - i <= S; ++j) { + if(A[j] > A[tgt]) { + tgt = j; + } + } + + S -= tgt - i; + + while(tgt - i > 0) { + int tmp = A[tgt]; A[tgt] = A[tgt-1]; A[tgt-1] = tmp; + --tgt; + } + } + } + + public static void main(String[] args) throws IOException { + N = readInt(); + A = new int[N]; + for(int i = 0; i < N; ++i) { + A[i] = readInt(); + } + S = readInt(); + + solution(); + + for(int i = 0; i < N; ++i) sb.append(A[i]).append(' '); + System.out.print(sb); + } + + static int readInt() throws IOException { + int c, n = 0; + while((c = System.in.read()) >= 0x30) n = (n << 3) + (n << 1) + (c & 0x0F); + if(c == '\r') System.in.read(); + return n; + } +} \ No newline at end of file diff --git "a/week19/Baekjoon_14442_\353\262\275\353\266\200\354\210\230\352\263\240\354\235\264\353\217\231\355\225\230\352\270\2602.java" "b/week19/Baekjoon_14442_\353\262\275\353\266\200\354\210\230\352\263\240\354\235\264\353\217\231\355\225\230\352\270\2602.java" new file mode 100644 index 0000000..bf5f8b0 --- /dev/null +++ "b/week19/Baekjoon_14442_\353\262\275\353\266\200\354\210\230\352\263\240\354\235\264\353\217\231\355\225\230\352\270\2602.java" @@ -0,0 +1,91 @@ +import java.io.*; +import java.util.*; + + +/** + * 시간: 298760ms + * 메모리: 692KB + */ +public class Baekjoon_14442_벽부수고이동하기2 { + // IO + static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + static StringBuilder sb = new StringBuilder(); + static StringTokenizer st; + // types + // constants + static final int[] dy = new int[]{0, 0, 1, -1}; + static final int[] dx = new int[]{1, -1, 0, 0}; + // variables + static int N, M, K; + static char[][] mat; + static int[][] isVisited; + + static int solution(){ + Deque q = new ArrayDeque<>(); + isVisited[0][0] = 0; + q.offerLast(new int[]{0, 0, 1}); + + while(!q.isEmpty()){ + int[] pos = q.pollFirst(); + int y = pos[1], x = pos[0], dist = pos[2]; + + for(int d = 0; d < dy.length; ++d){ + int ny = pos[1] + dy[d]; + int nx = pos[0] + dx[d]; + + if(0 <= ny && ny < N && 0 <= nx && nx < M) { + if (mat[ny][nx] == '1') { + // 이미 K번 벽을 부쉈다면 진행 불가 + if(isVisited[y][x] >= K) continue; + + // 이미 다른 노드에서 이 노드를 방문하였다면, 그 노드가 더 빠를 것이다. + // 하지만, 새로 방문하려는 노드가 벽을 부순 횟수가 앞선 노드 경로보다 더 적다면, + // 같거나 빠른 경로가 존재하므로 이때에만 재방문 한다. + if (isVisited[ny][nx] > isVisited[y][x] + 1) { + isVisited[ny][nx] = isVisited[y][x] + 1; + q.offerLast(new int[]{nx, ny, dist + 1}); + } + } else { + if (isVisited[ny][nx] > isVisited[y][x]) { + isVisited[ny][nx] = isVisited[y][x]; + q.offerLast(new int[]{nx, ny, dist + 1}); + + if(ny == N - 1 && nx == M - 1) return dist + 1; + } + } + } + } + } + return -1; + } + + public static void main(String[] args) throws IOException { + N = readInt(); + M = readInt(); + if(N == 1 && M == 1) { + System.out.print(1); + return; + } + K = readInt(); + + mat = new char[N][M]; + for(int i = 0; i < N; ++i) { + for(int j = 0; j < M; ++j) { + mat[i][j] = (char)System.in.read(); + } + System.in.read(); + } + + isVisited = new int[N][M]; + for(int i = 0; i < N; ++i) Arrays.fill(isVisited[i], Integer.MAX_VALUE); + + System.out.print(solution()); + } + + static int readInt() throws IOException{ + int c, n = 0; + while((c = System.in.read()) > 0x20) n = (n << 3) + (n << 1) + (c & 0x0F); + if(c == '\r') System.in.read(); + return n; + } +} \ No newline at end of file diff --git "a/week19/Baekjoon_1939_\354\244\221\353\237\211\354\240\234\355\225\234.java" "b/week19/Baekjoon_1939_\354\244\221\353\237\211\354\240\234\355\225\234.java" new file mode 100644 index 0000000..8e18910 --- /dev/null +++ "b/week19/Baekjoon_1939_\354\244\221\353\237\211\354\240\234\355\225\234.java" @@ -0,0 +1,83 @@ +import java.io.*; +import java.util.*; + + +/** + * 시간: 24644ms + * 메모리: 228KB + */ +public class Baekjoon_1939_중량제한 { + // IO + static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + static StringBuilder sb = new StringBuilder(); + static StringTokenizer st; + // types + static class Node implements Comparable { + int to, transfer; + + Node(int to, int transfer){ + this.to = to; + this.transfer = transfer; + } + + @Override + public int compareTo(Node other) { return other.transfer - this.transfer; } + } + // variables + static int N, M; + static List[] adj; + static int S, E; + static int[] maxTransfers; + + static int solution(){ + PriorityQueue q = new PriorityQueue<>(); + + maxTransfers[S] = 0; + for(Node node : adj[S]) { + maxTransfers[node.to] = node.transfer; + q.offer(node); + } + + while(!q.isEmpty()) { + Node node = q.poll(); + if(node.to == E) break; + + for(Node next : adj[node.to]){ + // 전체 경로에서 최소 중량 만큼만 전달가능하다. + int nextTransfer = Math.min(next.transfer, node.transfer); + if(maxTransfers[next.to] < nextTransfer){ + maxTransfers[next.to] = nextTransfer; + q.offer(new Node(next.to, nextTransfer)); + } + } + } + return maxTransfers[E]; + } + + public static void main(String[] args) throws IOException { + N = readInt(); + M = readInt(); + + adj = new ArrayList[N + 1]; + maxTransfers = new int[N + 1]; + for(int i = 1; i <= N; ++i) adj[i] = new ArrayList<>(); + + for(int i = 0; i < M; ++i) { + int s = readInt(), e = readInt(), w = readInt(); + adj[s].add(new Node(e, w)); + adj[e].add(new Node(s, w)); + } + + S = readInt(); + E = readInt(); + + System.out.print(solution()); + } + + static int readInt() throws IOException{ + int c, n = 0; + while((c = System.in.read()) > 0x20) n = (n << 3) + (n << 1) + (c & 0x0F); + if(c == '\r') System.in.read(); + return n; + } +} \ No newline at end of file diff --git "a/week20/Baekjoon_1464_\353\222\244\354\247\221\352\270\2603.java" "b/week20/Baekjoon_1464_\353\222\244\354\247\221\352\270\2603.java" new file mode 100644 index 0000000..faa54bd --- /dev/null +++ "b/week20/Baekjoon_1464_\353\222\244\354\247\221\352\270\2603.java" @@ -0,0 +1,46 @@ +import java.io.*; +import java.util.*; + + +/** + * 시간: 68ms + * 메모리: 11492KB + */ +public class Baekjoon_1464_뒤집기3 { + // Input Handler + static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + static StringBuilder sb = new StringBuilder(); + static StringTokenizer st = null; + // types + // constants + // variables + static char[] word; + static int[] min; + static char[] result; + + public static void main(String[] args) throws IOException { + word = br.readLine().toCharArray(); + min = new int[word.length]; + result = new char[word.length]; + + min[0] = word[0]; + for(int i = 1; i < word.length; ++i) { + min[i] = Math.min(min[i-1], word[i]); + } + + int lcur = 0, rcur = word.length - 1; + for(int i = word.length - 1; i >= 0; --i) { + if(min[i] == word[i]) result[lcur++] = word[i]; + else result[rcur--] = word[i]; + } + + System.out.print(result); + } + + static int readInt() throws IOException { + int c, n = 0; + while((c = System.in.read()) >= 0x30) n = (n << 3) + (n << 1) + (c & 0x0F); + if(c == '\r') System.in.read(); + return n; + } +} \ No newline at end of file diff --git "a/week20/Baekjoon_1477_\355\234\264\352\262\214\354\206\214\354\204\270\354\232\260\352\270\260.java" "b/week20/Baekjoon_1477_\355\234\264\352\262\214\354\206\214\354\204\270\354\232\260\352\270\260.java" new file mode 100644 index 0000000..00cb4d9 --- /dev/null +++ "b/week20/Baekjoon_1477_\355\234\264\352\262\214\354\206\214\354\204\270\354\232\260\352\270\260.java" @@ -0,0 +1,53 @@ +import java.io.*; +import java.util.*; + +/** + * 시간: 72ms + * 메모리: 11552KB + */ +public class Baekjoon_1477_휴게소세우기 { + // Input Handler + static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + static StringBuilder sb = new StringBuilder(); + static StringTokenizer st = null; + // types + // constants + // variables + static int N, M, L; + static int[] locations; + + static boolean isVaild(int limit) { + int cnt = 0; + for(int i = 1; i < locations.length; ++i) { + cnt += ((locations[i] - locations[i - 1]) - 1) / limit; + } + return cnt <= M; + } + + public static void main(String[] args) throws IOException { + N = readInt(); + M = readInt(); + L = readInt(); + + locations = new int[N+2]; + locations[0] = 0; + for(int i = 1; i <= N; ++i) locations[i] = readInt(); + locations[N + 1] = L; + Arrays.sort(locations); + + int lo = 1, hi = L; + while(lo < hi) { + int mid = (lo + hi) >> 1; + if(isVaild(mid)) hi = mid; + else lo = mid + 1; + } + System.out.print(lo); + } + + static int readInt() throws IOException { + int c, n = 0; + while((c = System.in.read()) >= 0x30) n = (n << 3) + (n << 1) + (c & 0x0F); + if(c == '\r') System.in.read(); + return n; + } +} \ No newline at end of file diff --git "a/week20/Beakjoon_4179_\353\266\210.java" "b/week20/Beakjoon_4179_\353\266\210.java" new file mode 100644 index 0000000..fa5b8db --- /dev/null +++ "b/week20/Beakjoon_4179_\353\266\210.java" @@ -0,0 +1,83 @@ +import java.io.*; +import java.util.*; + + +/** + * 시간: 456ms + * 메모리: 47008KB + */ +public class Beakjoon_4179_불 { + // Input Handler + static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + static StringBuilder sb = new StringBuilder(); + static StringTokenizer st = null; + // types + // constants + static int[] dy = {0,0,1,-1}; + static int[] dx = {1,-1,0,0}; + // variables + static int R, C; + static char[][] mat; + static Deque jihon = new ArrayDeque(); + static Deque fire = new ArrayDeque(); + + static int solution() { + while(!jihon.isEmpty()) { + for(int i = 0, n = jihon.size(); i < n; ++i) { + int[] node = jihon.pollFirst(); + int x = node[0], y = node[1], d = node[2]; + + if(mat[y][x] == 'F') continue; + if((x == 0 || x == C - 1) || (y == 0 || y == R - 1)) return d; + + for(int di = 0; di < dy.length; ++di) { + int nx = x + dx[di], ny = y + dy[di]; + if(nx < 0 || C <= nx || ny < 0 || R <= ny) continue; + if(mat[ny][nx] != '.') continue; + + jihon.offerLast(new int[] {nx, ny, d+1}); + mat[ny][nx] = 'J'; + } + } + + for(int i = 0, n = fire.size(); i < n; ++i) { + int[] node = fire.pollFirst(); + int x = node[0], y = node[1]; + + for(int di = 0; di < dy.length; ++di) { + int nx = x + dx[di], ny = y + dy[di]; + if(nx < 0 || C <= nx || ny < 0 || R <= ny) continue; + if(mat[ny][nx] == '#' || mat[ny][nx] == 'F') continue; + + fire.offerLast(new int[] {nx, ny}); + mat[ny][nx] = 'F'; + } + } + } + + return -1; + } + + public static void main(String[] args) throws IOException { + R = readInt(); + C = readInt(); + mat = new char[R][]; + for(int i = 0; i < R; ++i) { + mat[i] = br.readLine().toCharArray(); + for(int j = 0; j < C; ++j) { + if(mat[i][j] == 'J') jihon.offer(new int[] {j, i, 1}); + else if(mat[i][j] == 'F') fire.offer(new int[] {j, i}); + } + } + + int ans = solution(); + System.out.print(ans <= 0 ? "IMPOSSIBLE" : ans); + } + + static int readInt() throws IOException { + int c, n = 0; + while((c = System.in.read()) >= 0x30) n = (n << 3) + (n << 1) + (c & 0x0F); + if(c == '\r') System.in.read(); + return n; + } +} \ No newline at end of file