일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 백준 2473번 세 용액 - java
- HashMap
- 프로그래머스 java
- 코틀린기초
- 프로그래머스
- mysql hy000 에러
- Java
- map
- StringBuilder
- 백준 1197번 최소 스패닝 트리 - java
- toUpperCase
- HashSet
- 18111번 마인크래프트 - java 구현
- 프로그래머스 자바
- StringTokenizer
- 백준 1043번 거짓말 - java 분리 집합
- ac 5430번
- 백준 1541
- 백준 1806번 부분합 java
- 최소 힙 1927
- kotlin
- 백준 1647번 도시 분할 계획 - java
- append
- 백준 3190번
- replace()
- dp
- Stack
- 백준 14938번 서강그라운드
- hash
- 백준 2467번 용액 자바 - 이분탐색
- Today
- Total
말하는 컴공감자의 텃밭
알고리즘 재활치료 14일차 - 10816, 15666, 1504번 본문
숫자 카드 2
카드의 개수가 몇개인지 파악해야하고, 없다면 0을 출력해야한다.
간단하게 HashMap 자료구조를 활용했고 getOrDefault 를 활용해서 개수 저장해줬다.
5분커엇..
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | import java.io.*; import java.util.*; public class Main { // 숫자 카드 2 public static int N, M; public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer st = new StringTokenizer(br.readLine()); StringBuilder sb = new StringBuilder(); N = Integer.parseInt(st.nextToken()); Map<Integer, Integer> set = new HashMap<>(); st = new StringTokenizer(br.readLine()); for(int i = 0; i<N; i++){ int temp = Integer.parseInt(st.nextToken()); set.put (temp,set.getOrDefault(temp, 0) + 1 ); } st = new StringTokenizer(br.readLine()); M = Integer.parseInt(st.nextToken()); st = new StringTokenizer(br.readLine()); for(int i = 0; i<M; i++){ int temp = Integer.parseInt(st.nextToken()); if(set.get(temp) == null){ sb.append(0).append(" "); }else{ sb.append(set.get(temp)).append(" "); } } System.out.println(sb); } } | cs |
N과 M (12)
N과 M도 곧 다 풀어가네..
이번 12번은 중복되는 숫자를 사용해두 되지만 중복되는 수열만 사용안하면 된다.
또한 비내림차순으로 우측하단으로 갈수록 숫자가 커져야 한다.
start 변수로 반복함에 따라서 정렬된 arr에서 밀리지 않게 해주었다.
만약 숫자 N = 4, M = 2이고 숫자가 1,2,3,4 라면
1 1
1 2
1 3
1 4 이런식으로 진행하는 역할이다.
이렇게 작성하려면 중복되는 숫자들을 지워줘야 했기에 Set으로 제거하고 asArray쓰려다가
Stream을 연습중이라 사용해봤다.
Array를 먼저 Stream으로 변환해주고 distinct()를 활용해서 제거해줬다. 이후 다시 toArray로 바꿔주면 끝.
arr = Arrays.stream(arr).distinct().toArray();
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | import java.io.*; import java.util.*; public class Main { // N과 M (12) public static int N, M; public static int[] arr; public static StringBuilder sb = new StringBuilder(); 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()); arr = new int[N]; st = new StringTokenizer(br.readLine()); for (int i = 0; i < N; i++) { arr[i] = Integer.parseInt(st.nextToken()); } arr = Arrays.stream(arr).distinct().toArray(); Arrays.sort(arr); N = arr.length; // 중복 제거 후 크기 조정 dfs(0, 0, new int[M]); System.out.println(sb); } public static void dfs(int depth, int start, int[] answer) { if (depth == M) { for (int s : answer) { sb.append(s).append(" "); } sb.append("\n"); return; } for (int i = start; i < N; i++) { answer[depth] = arr[i]; dfs(depth + 1, i, answer); } } } | cs |
특정한 최단 경로
먼저 방향성이 없는 그래프가 주어지고, 1번부터 N번까지 도달하는데 이 중간에 두개의 정점을 꼮!!! 지나쳐야 한다.
한번 이동했던 간선도 다시 이동할 수 있다는 조건이 있어서 오히려 헷갈렸는데,
단순히 해당 위치에서 다익스트라 로직을 사용해주면 해결됐다.
다익스트라는 1에서 2로 이동하는데, 1->2 보다 cost가 적은 다른 경로들이 있다면 갱신하면서
출발점에서 모든 vertex까지의 비용을 갱신하는 알고리즘이다.
예제처럼 1부터 4까지 가는데, 2와 3을 꼭 지나쳐야 하는 경우를 계산해야 한다.
경로는 1 - 2 - 3 - 4 아니면 1 - 3 - 2 - 4 이고
이중에 짧은걸 고르면 된다. 따라서 중간에 방문하는 경로를 route1, route2로 나눈다면
( start -> route1 ) + ( route1 > route2 ) + ( route2 > end ) 가 1번 Path일것이고
( start -> route2 ) + ( route2 > route1 ) + ( route1 > end ) 가 2번 Path이 된다.
이 둘중에서 더 짧은걸 출력해주면 되고, Integer.MAX_VALUE; 로 INF 를 표기했을때 덧셈하면 오버라이드되니
가볍게 처리해주자. INF라면 경로가 없는것이므로 -1를 출력해주었다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | import java.io.*; import java.util.*; public class Main { // 특정한 최단 경로 public static int N, E; public static ArrayList<ArrayList<Node>> graph; public static int[] costs; 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()); E = Integer.parseInt(st.nextToken()); graph = new ArrayList<>(); for (int i = 0; i <= N; i++) { graph.add(new ArrayList<Node>()); } for (int i = 0; i < E; i++) { st = new StringTokenizer(br.readLine()); int start = Integer.parseInt(st.nextToken()); int end = Integer.parseInt(st.nextToken()); int cost = Integer.parseInt(st.nextToken()); // 양방향 graph.get(start).add(new Node(end, cost)); graph.get(end).add(new Node(start, cost)); } st = new StringTokenizer(br.readLine()); int route1 = Integer.parseInt(st.nextToken()); int route2 = Integer.parseInt(st.nextToken()); int case1 = 0, case2 = 0; int path1 = dij(1, route1); int path2 = dij(route1, route2); int path3 = dij(route2, N); if (NonePathChk(path1, path2, path3)) { case1 = Integer.MAX_VALUE; } else { case1 = path1 + path2 + path3; } path1 = dij(1, route2); path2 = dij(route2, route1); path3 = dij(route1, N); if (NonePathChk(path1, path2, path3)) { case2 = Integer.MAX_VALUE; } else { case2 = path1 + path2 + path3; } int answer = Math.min(case1, case2); // 없는 경로 처리 if (answer == Integer.MAX_VALUE) { System.out.println("-1"); } else { System.out.println(answer); } } public static int dij(int start, int end) { costs = new int[N + 1]; Arrays.fill(costs, Integer.MAX_VALUE); PriorityQueue<Node> pq = new PriorityQueue<>(Comparator.comparingInt(o -> o.cost)); pq.add(new Node(start, 0)); costs[start] = 0; while (!pq.isEmpty()) { Node cur = pq.poll(); int curV = cur.vertex; int curC = cur.cost; if (costs[curV] < curC) { continue; } for (Node next : graph.get(curV)) { int newC = curC + next.cost; if (newC < costs[next.vertex]) { costs[next.vertex] = newC; pq.add(new Node(next.vertex, newC)); } } } return costs[end]; } public static boolean NonePathChk(int a, int b, int c) { return (a == Integer.MAX_VALUE || b == Integer.MAX_VALUE || c == Integer.MAX_VALUE); } public static class Node { int vertex; int cost; Node(int vertex, int cost) { this.vertex = vertex; this.cost = cost; } } } | cs |
'알고리즘 > Backjoon - Java' 카테고리의 다른 글
백준 1806번 부분합 - Java 투 포인터 (0) | 2024.08.21 |
---|---|
알고리즘 재활 15일차 - 11723, 1927, 5430번 (0) | 2024.08.19 |
알고리즘 재활 13일차 - 15663, 1149, 1753번 (0) | 2024.08.15 |
알고리즘 재활 12일차 - 백준 2869, 15654, 16236번 (0) | 2024.08.14 |
알고리즘 재활 11일차 - 백준 9461, 5525, 1389번 (0) | 2024.08.14 |