diff --git a/youtube/BOJ2749.java b/youtube/BOJ2749.java new file mode 100644 index 0000000..dddccf8 --- /dev/null +++ b/youtube/BOJ2749.java @@ -0,0 +1,67 @@ +import java.io.*; + +public class Main { + // 문제에서 요구한 나누는 수 + final static long MOD = 1000000; + + public static void main(String[] args) throws IOException { + // 입력 속도를 위해 BufferedReader 사용 + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + + // n은 최대 100경(10^18)이므로 long 사용 + long n = Long.parseLong(br.readLine()); + + // F_0 = 0 + if (n == 0) { + System.out.println(0); + return; + } + + // 피보나치 Q-행렬 기본값 + long[][] A = {{1, 1}, {1, 0}}; + + // 행렬 거듭제곱으로 Fn 구하기 + long[][] result = power(A, n); + + // M^n의 [0][1] 성분이 F_n임 + System.out.println(result[0][1] % MOD); + } + + // 분할 정복을 이용한 거듭제곱 (O(logN)) + private static long[][] power(long[][] A, long n) { + // 지수가 1이면 자기 자신 반환 (Base Case) + if (n == 1) { + // 반환할 때도 모듈러 연산 안전하게 한 번 해줌 + return new long[][] { + {A[0][0] % MOD, A[0][1] % MOD}, + {A[1][0] % MOD, A[1][1] % MOD} + }; + } + + // 1. 반으로 쪼개서 구함 (Divide) + long[][] half = power(A, n / 2); + + // 2. 구한 것을 제곱함 (Conquer) + long[][] result = multiply(half, half); + + // 3. 홀수라면 A를 한 번 더 곱해줌 + if (n % 2 == 1) { + result = multiply(result, A); + } + + return result; + } + + // 행렬 곱셈 함수 (나머지 연산 포함) + private static long[][] multiply(long[][] o1, long[][] o2) { + long[][] ret = new long[2][2]; + + // 2x2 행렬 곱셈 공식 + 모듈러 연산 + ret[0][0] = (o1[0][0] * o2[0][0] + o1[0][1] * o2[1][0]) % MOD; + ret[0][1] = (o1[0][0] * o2[0][1] + o1[0][1] * o2[1][1]) % MOD; + ret[1][0] = (o1[1][0] * o2[0][0] + o1[1][1] * o2[1][0]) % MOD; + ret[1][1] = (o1[1][0] * o2[0][1] + o1[1][1] * o2[1][1]) % MOD; + + return ret; + } +} diff --git "a/\352\267\270\353\236\230\355\224\204/P1325_\355\232\250\354\234\250\354\240\201\354\235\270\355\225\264\355\202\271.java" "b/\352\267\270\353\236\230\355\224\204/P1325_\355\232\250\354\234\250\354\240\201\354\235\270\355\225\264\355\202\271.java" index 2e4334d..98ea35c 100644 --- "a/\352\267\270\353\236\230\355\224\204/P1325_\355\232\250\354\234\250\354\240\201\354\235\270\355\225\264\355\202\271.java" +++ "b/\352\267\270\353\236\230\355\224\204/P1325_\355\232\250\354\234\250\354\240\201\354\235\270\355\225\264\355\202\271.java" @@ -1,59 +1,59 @@ import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.io.IOException; import java.io.InputStreamReader; -import java.io.OutputStreamWriter; -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.Queue; -import java.util.StringTokenizer; +import java.util.*; public class P1325_효율적인해킹 { - static int N, M; - static boolean visited[]; - static int answer[]; - static ArrayList A[]; - public static void main(String[] args) throws IOException { - BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); - BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out)); - StringTokenizer st = new StringTokenizer(br.readLine()); - N = Integer.parseInt(st.nextToken()); - M = Integer.parseInt(st.nextToken()); - A = new ArrayList[N + 1]; - answer = new int[N + 1]; - for (int i = 1; i <= N; i++) - A[i] = new ArrayList<>(); - for (int i = 0; i < M; i++) { - st = new StringTokenizer(br.readLine()); - int S = Integer.parseInt(st.nextToken()); - int E = Integer.parseInt(st.nextToken()); - A[S].add(E); - } - for (int i = 1; i <= N; i++) { //모든 정점에 대하여 BFS 실행 - visited = new boolean[N + 1]; - BFS(i); - } - int maxVal = 0; - for (int i = 1; i <= N; i++) { - maxVal = Math.max(maxVal, answer[i]); - } - for (int i = 1; i <= N; i++) { - if (answer[i] == maxVal) //answer배열에서 maxVal와 같은 값을 가진 index를 정답으로 출력 - System.out.print(i + " "); + static boolean visited[] = new boolean[10001];; + static int answer[] = new int[10001];; + static ArrayList A[] = new ArrayList[10001];; + + static Queue queue = new ArrayDeque(); + public static void main(String[] args) throws Exception { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st = new StringTokenizer(br.readLine()); + int N = Integer.parseInt(st.nextToken()); + int M = Integer.parseInt(st.nextToken()); + + for (int i = 1; i <= N; i++) + A[i] = new ArrayList<>(); + for (int i = 0; i < M; i++) { + st = new StringTokenizer(br.readLine()); + int S = Integer.parseInt(st.nextToken()); + int E = Integer.parseInt(st.nextToken()); + A[S].add(E); + } + for (int i = 1; i <= N; i++) { //모든 정점에 대하여 BFS 실행 + for (int j = 1; j <= N; j++) { + visited[j] = false; + } + + BFS(i); + } + + int maxVal = 0; + for (int i = 1; i <= N; i++) { + if (maxVal < answer[i]) { + maxVal = answer[i]; + } + } + + StringBuilder sb = new StringBuilder(); + for (int i = 1; i <= N; i++) { + if (answer[i] == maxVal) //answer배열에서 maxVal와 같은 값을 가진 index를 정답으로 출력 + sb.append(i).append(" "); + } + System.out.println(sb); } - } - public static void BFS(int index) { - Queue queue = new LinkedList(); - queue.add(index); - visited[index] = true; - while (!queue.isEmpty()) { - int now_node = queue.poll(); - for (int i : A[now_node]) { - if (visited[i] == false) { - visited[i] = true; - answer[i]++; //신규 정점인덱스의 정답 배열 값을 증가 시키기 - queue.add(i); + public static void BFS(int index) { + queue.add(index); + visited[index] = true; + while (!queue.isEmpty()) { + int now_node = queue.poll(); + for (int i : A[now_node]) { + if (visited[i]) continue; + visited[i] = true; + answer[i]++; //신규 정점인덱스의 정답 배열 값을 증가 시키기 + queue.add(i); + } } - } } - } -} \ No newline at end of file +} diff --git "a/\353\217\231\354\240\201\352\263\204\355\232\215\353\262\225/P13398_\354\227\260\354\206\215\353\220\234\354\240\225\354\210\230\354\235\230\355\225\251.java" "b/\353\217\231\354\240\201\352\263\204\355\232\215\353\262\225/P13398_\354\227\260\354\206\215\355\225\2512.java" similarity index 94% rename from "\353\217\231\354\240\201\352\263\204\355\232\215\353\262\225/P13398_\354\227\260\354\206\215\353\220\234\354\240\225\354\210\230\354\235\230\355\225\251.java" rename to "\353\217\231\354\240\201\352\263\204\355\232\215\353\262\225/P13398_\354\227\260\354\206\215\355\225\2512.java" index 4788c7e..26d0fd9 100644 --- "a/\353\217\231\354\240\201\352\263\204\355\232\215\353\262\225/P13398_\354\227\260\354\206\215\353\220\234\354\240\225\354\210\230\354\235\230\355\225\251.java" +++ "b/\353\217\231\354\240\201\352\263\204\355\232\215\353\262\225/P13398_\354\227\260\354\206\215\355\225\2512.java" @@ -1,7 +1,7 @@ import java.io.*; import java.util.StringTokenizer; -public class P13398_연속된정수의합 { +public class P13398_연속합2 { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out)); @@ -36,3 +36,4 @@ public static void main(String[] args) throws IOException { br.close(); } } + diff --git "a/\354\240\225\353\240\254/P11004_K\353\262\210\354\247\270\354\210\230.java" "b/\354\240\225\353\240\254/P11004_K\353\262\210\354\247\270\354\210\230.java" index e6833e4..a0aebe0 100644 --- "a/\354\240\225\353\240\254/P11004_K\353\262\210\354\247\270\354\210\230.java" +++ "b/\354\240\225\353\240\254/P11004_K\353\262\210\354\247\270\354\210\230.java" @@ -3,7 +3,7 @@ import java.io.InputStreamReader; import java.util.StringTokenizer; -public class Main { +public class P11004_K번째수 { public static void main(String[] args) throws IOException { BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer st = new StringTokenizer(in.readLine()); diff --git "a/\354\240\225\353\240\254/P1377_\353\262\204\353\270\224\354\206\214\355\212\2701.java" "b/\354\240\225\353\240\254/P1377_\353\262\204\353\270\224\354\240\225\353\240\2541.java" similarity index 93% rename from "\354\240\225\353\240\254/P1377_\353\262\204\353\270\224\354\206\214\355\212\2701.java" rename to "\354\240\225\353\240\254/P1377_\353\262\204\353\270\224\354\240\225\353\240\2541.java" index aea547c..725f9d5 100644 --- "a/\354\240\225\353\240\254/P1377_\353\262\204\353\270\224\354\206\214\355\212\2701.java" +++ "b/\354\240\225\353\240\254/P1377_\353\262\204\353\270\224\354\240\225\353\240\2541.java" @@ -2,7 +2,7 @@ import java.io.IOException; import java.io.InputStreamReader; import java.util.Arrays; -public class P1377_버블소트1 { +public class P1377_버블정렬1 { public static void main(String[] args) throws IOException { BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); int N = Integer.parseInt(reader.readLine()); @@ -36,3 +36,4 @@ public int compareTo(mData o) {//value 기준 오름차순 정렬 } } + diff --git "a/\354\240\225\353\240\254/P1517_\353\262\204\353\270\224\354\206\214\355\212\2702.java" "b/\354\240\225\353\240\254/P1517_\353\262\204\353\270\224\354\240\225\353\240\2542.java" similarity index 94% rename from "\354\240\225\353\240\254/P1517_\353\262\204\353\270\224\354\206\214\355\212\2702.java" rename to "\354\240\225\353\240\254/P1517_\353\262\204\353\270\224\354\240\225\353\240\2542.java" index b3cce26..bef6541 100644 --- "a/\354\240\225\353\240\254/P1517_\353\262\204\353\270\224\354\206\214\355\212\2702.java" +++ "b/\354\240\225\353\240\254/P1517_\353\262\204\353\270\224\354\240\225\353\240\2542.java" @@ -3,7 +3,7 @@ import java.io.InputStreamReader; import java.util.Arrays; import java.util.StringTokenizer; -public class P1517_버블소트2 { +public class P1517_버블정렬2 { public static int[] A, tmp; public static long result; public static void main(String[] args) throws IOException { @@ -58,3 +58,4 @@ private static void merget_sort(int s, int e) { } } + diff --git "a/\355\203\220\354\203\211/P1206_DFS\354\231\200BFS.java" "b/\355\203\220\354\203\211/P1260_DFS\354\231\200BFS.java" similarity index 94% rename from "\355\203\220\354\203\211/P1206_DFS\354\231\200BFS.java" rename to "\355\203\220\354\203\211/P1260_DFS\354\231\200BFS.java" index 9e991c2..932aee5 100644 --- "a/\355\203\220\354\203\211/P1206_DFS\354\231\200BFS.java" +++ "b/\355\203\220\354\203\211/P1260_DFS\354\231\200BFS.java" @@ -1,5 +1,5 @@ import java.util.*; -public class P1206_DFS와BFS { +public class P1260_DFS와BFS { static boolean visited[]; static ArrayList[] A; public static void main(String[] args) { @@ -57,3 +57,4 @@ private static void BFS(int node) { // BFS구현 } } } + diff --git "a/\355\203\220\354\203\211/P15649_N\352\263\274M.java" "b/\355\203\220\354\203\211/P15649_N\352\263\274M.java" new file mode 100644 index 0000000..500601f --- /dev/null +++ "b/\355\203\220\354\203\211/P15649_N\352\263\274M.java" @@ -0,0 +1,39 @@ +import java.util.Scanner; + +public class P15649_N과M { + static int N, M; + static boolean[] V; // 숫자 사용 여부 저장 + static int[] S; // 수열 정보 저장 + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + N = sc.nextInt(); + M = sc.nextInt(); + S = new int[N]; + V = new boolean[N]; + backtracking(0); + } + + private static void backtracking(int length) { + if (length == M) { // 길이가 M인 수열이 만들어진 경우 + printArray(); + return; + } + for (int i = 0; i < N; i++) { + if (!V[i]) { + V[i] = true; //수 사용여부 저장 + S[length] = i; //수열에 수 사용하기 + backtracking(length + 1); + V[i] = false; //수 반납여부 저장 + } + } + } + + private static void printArray() { // 수열 내용 출력 + for (int i = 0; i < M; i++) { + System.out.print(S[i] + 1 + " "); + } + System.out.println(); + } + +} diff --git "a/\355\203\220\354\203\211/P17136_\354\203\211\354\242\205\354\235\264\353\266\231\354\235\264\352\270\260.java" "b/\355\203\220\354\203\211/P17136_\354\203\211\354\242\205\354\235\264\353\266\231\354\235\264\352\270\260.java" new file mode 100644 index 0000000..aa50009 --- /dev/null +++ "b/\355\203\220\354\203\211/P17136_\354\203\211\354\242\205\354\235\264\353\266\231\354\235\264\352\270\260.java" @@ -0,0 +1,71 @@ +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.StringTokenizer; + +public class P17136_색종이붙이기 { + + static int[][] M = new int[10][10]; + static int[] S = {0, 5, 5, 5, 5, 5}; // 남은 색종이 수 + static int result = Integer.MAX_VALUE; // 최소 사용 갯수 + + public static void main(String[] args) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + for (int i = 0; i < 10; i++) { + StringTokenizer st = new StringTokenizer(br.readLine()); + for (int j = 0; j < 10; j++) { + M[i][j] = Integer.parseInt(st.nextToken()); + } + } + // 1이 적힌 모든 칸을 붙이는 색종이를 사용한 경우의 수를 백트래킹으로 탐색 + Backtracking(0, 0); + if (result == Integer.MAX_VALUE) { + System.out.println(-1); + } else { + System.out.println(result); + } + } + + static void Backtracking(int xy, int useCnt) { + if (xy == 100) { //색종이로 1이 적힌 모든 칸을 붙였을 때 (x, y 좌표를 끝까지 탐색 한 경우 ) 탐색 종료 + result = Math.min(useCnt, result); + return; + } + int x = xy % 10; + int y = xy / 10; + + //가지치기 : 최소로 사용한 색종이 수보다 현재 탐색에서 사용한 색종이 수가 많으면 더이상 탐색 불필요 + if (result <= useCnt) return; + if (M[y][x] == 1) { + for (int i = 5; i > 0; i--) { + if (S[i] > 0 && check(x, y, i)) { + S[i]--; // 종이 사용하기 + fill(x, y, i, 0); // 종이 붙이기: 종이로 덮이는 부분 1-> 0으로 변경 + Backtracking(xy + 1, useCnt + 1); + S[i]++; // 사용한 종이 다시 채우기 + fill(x, y, i, 1); // 종이 떼어내기 : 기존에 덮인 부분 0 -> 1 값으로 변경 + } + } + } else { + Backtracking(xy + 1, useCnt); // 현재 좌표의 값이 0이면 색종이를 사용하지 않고 다음 칸 이동 + } + } + + static void fill(int x, int y, int size, int num) { + for (int i = y; i < y + size; i++) { + for (int j = x; j < x + size; j++) { + M[i][j] = num; + } + } + } + + static boolean check(int x, int y, int size) { + if (x + size > 10 || y + size > 10) return false; + for (int i = y; i < y + size; i++) { + for (int j = x; j < x + size; j++) { + if (M[i][j] != 1) return false; + } + } + return true; + } +} diff --git "a/\355\203\220\354\203\211/P9663_NQueen.java" "b/\355\203\220\354\203\211/P9663_NQueen.java" new file mode 100644 index 0000000..2ac805b --- /dev/null +++ "b/\355\203\220\354\203\211/P9663_NQueen.java" @@ -0,0 +1,36 @@ +import java.util.Scanner; + +public class P9663_NQueen { + static int[] A; //퀸 배치 정보 저장 + static int N; //체스판 크기 N*N + static int cnt = 0; //퀸을 배치하는 경우의 수 저장 + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + N = sc.nextInt(); + A = new int[N]; + backtracking(0); + System.out.println(cnt); + } + + private static void backtracking(int row) { + if (row == N) { // 퀸 N개 모두 배치한 경우 + cnt++; + return; + } + for (int i = 0; i < N; i++) { + A[row] = i; + if (check(row)) { //이번에 배치한 퀸이 전에 배치했던 퀸들과 서로 공격할 수 없는지 체크 + backtracking(row + 1); + } + } + } + + private static boolean check(int row) { + for (int i = 0; i < row; i++) { + if (A[i] == A[row]) return false; // 일직선 배치되어 있는 경우 + if (Math.abs(row - i) == Math.abs(A[i] - A[row])) return false; // 대각선으로 배치되어 있는 경우 + } + return true; + } +}