본문 바로가기
섬나라 아일랜드(DFS) N*N의 섬나라 아일랜드, 섬은 1, 바다는 0 섬은 상하좌우 + 대각선 8방향 섬이 몇개인지 구하는 문제, 그림은 섬이 5개 입력 7 1 1 0 0 0 1 0 0 1 1 0 1 1 0 0 1 0 0 0 0 0 0 0 0 1 0 1 1 1 1 0 1 1 0 0 1 0 0 0 1 0 0 1 0 1 0 1 0 0 출력 5 기존에 상하좌우 dx,dy배열에 대각선을 넣고 dfs로 섬을 판단하는 문제 Solution 함수로 보드 전체를 2중 for문을 돌면서 바다가 아닌 땅이 나오면 DFS 함수로 그 섬의 주변에도 갈수 있는 땅이 나오는지 판단한다 Solution 함수에서 땅을 발견하면 카운트를 늘려주고 DFS 함수를 호출, DFS함수가 주변이 전부 바다일때 까지 돌고 다시 Solution 함수로 돌아와서 이어서.. 2023. 9. 3.
토마토(BFS 활용) .토마토는 아래의 그림과 같이 격자 모양 상자의 칸에 하나씩 넣어서 창고에 보관한다. 창고에 보관되는 토마토들 중에는 잘 익은 것도 있지만, 아직 익지 않은 토마토들도 있을 수 있다. 보관 후 하루가 지나면, 익은 토마토들의 인접한 곳에 있는 익지 않은 토마토들은 익은 토마토의 영향을 받아 익게 된다. 하나의 토마토의 인접한 곳은 왼쪽, 오른쪽, 앞, 뒤 네 방향에 있는 토마토를 의미한다. 대각선 방향에 있는 토마토들에게는 영향을 주지 못하며, 토마토가 혼자 저절로 익는 경우는 없다고 가정한다. 현수는 창고에 보관된 토마토들이 며칠이 지나면 다 익게 되는지, 그 최소 일수를 알고 싶어 한다. 토마토를 창고에 보관하는 격자모양의 상자들의 크기와 익은 토마토들과 익지 않은 토마토들의 정보가 주어졌을 때, 며.. 2023. 9. 1.
미로의 최단거리(BFS) 뭔가 기존 자료형으로 안될거 같으면 클래스를 만들어서 사용해보자 7*7 격자판 미로를 탈출하는 최단경로의 길이를 출력 입력 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 1 0 0 0 1 1 0 1 0 1 1 1 1 0 1 0 0 0 1 0 0 0 1 0 0 1 0 1 0 0 0 0 출력. 도착할 수 없으면 -1를 출력한다. 12 풀이 한 지점에서 상하좌우 지점으로 이동하는 것을 레벨 탐색으로 생각하고 board 배열 이동 횟수를 저장할 dis 배열을 만든 후 이동할때마다 기존 배열의 이동횟수 +1을 하면서 레벨 탐색한다, 마지막에 dis[7][7] 칸이 0이면 마지막 칸 까지 도달한 방법이 없는거라 -1, 아니면 dis[7][7]의 값을 리턴한다 일단 좌표를 저장할 Pointer 클래스를.. 2023. 8. 31.
DFS 미로찾기 7*7 격자판 미로를 탈출하는 경로의 가지수를 출력하는 프로그램을 작성하세요. 출발점은 격자의 (1, 1) 좌표이고, 탈출 도착점은 (7, 7)좌표이다. 격자판의 1은 벽이고, 0은 통로이다. 격자판의 움직임은 상하좌우로만 움직인다. 미로가 다음과 같다면 입력 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 1 0 0 0 1 1 0 1 0 1 1 1 1 0 0 0 0 1 1 1 0 1 1 0 0 1 0 0 0 0 0 0 출력 8 DFS로 dx,dy배열을 순회하면서 갈수 있는 칸이면 가고 간 칸은 체크, 갔다가 돌아오면서 체크 해제 하는 방법으로 푼다 DFS 함수 내부에서는 갈수 있는 칸인지 판별하기 위해서 범위를 확인하고 넘어간다 import java.util.Scanner; public c.. 2023. 8. 31.
자바로 만들기 단축키 - 설정 keymap에서 볼수 있음 alt + insert로 generate 해서 생성자,get,set 등 쉽게 만들 수 있음 ctrl + alt + v - 타입?을 알아서 만들어줌 psvm - public static void main메인 함수 만들때 psvm 치고 엔터누르면 바로 생성 ctrl + shift + t dip 위반 이렇게 기능을 확장해서 변경하면 클라이언트 코드에도 영향을 준다 -> ocp 위반 문제 해결하기 dip 위반하는걸 추상(인터페이스)에만 의존하게 의존관계를 변경하면 된다 private DiscountPolicy discountPolicy; 2023. 8. 31.
iterator, Listiterator List 컬렉션 클래스에서만 Listiterator를 사용 가능하다 LinkedList l = new LinkedList(); 로 이중연결리스트를 만들고 나서 ListIterator it = l.listIterator();를 선언해서 위의 Linkedlist를 순회하는 Listiterator를 사용할 수 있다..hasNext(), .hasPrevious(), .hasNext() - 앞이나 뒤에 요소가 있는지 확인 .next(), .previous() - 이동하면서 값을 반환 remove - 현재 it 위치에 있는 요소를 제거, add(E) - 현재 it 위치에 E를 추가 2023. 8. 27.
LinkedList(이중 연결 리스트) https://www.codetree.ai/missions/6/problems/integer-command-processing-8?&utm_source=clipboard&utm_medium=text LinkedList l = new LinkedList(); 형태로 이중연결리스트 사용 addFirst(E) - 맨 앞에 데이터 E를 추가 addLast(E) - 맨 뒤에 데이터 E를 추가 pollFirst() - 맨 앞에 있는 데이터를 반환하면서 리스트에서 삭제 pollLast() - 맨 뒤에 있는 데이터를 반환하며서 리스트에서 삭제 size() - 현재 list에 들어있는 데이터의 수 isEmpty() - 현재 list가 비어있다면 true, 아니라면 false peekFirst() - list의 맨 앞에 .. 2023. 8. 27.
동적 배열 https://www.codetree.ai/missions/6/problems/process-numeric-commands-5?&utm_source=clipboard&utm_medium=text 코드트리 | 코딩테스트 준비를 위한 알고리즘 정석 국가대표가 만든 코딩 공부의 가이드북 코딩 왕초보부터 꿈의 직장 코테 합격까지, 국가대표가 엄선한 커리큘럼으로 준비해보세요. www.codetree.ai ArrayList name = new ArrayList(); 형태로 동적 배열을 선언 add, remove, get, size 등의 인덱스가 있다 ArrayList 등 컬렉션에 정의되어 있는 자료구조 순회 - iterator 반복자 ArrayList v = new ArrayList(); Iterator itera.. 2023. 8. 27.
조합 구하기 1부터 N까지 번호가 적힌 구슬이 있습니다. 이 중 M개를 뽑는 방법의 수를 출력하는 프로그 램을 작성하세요.출력순서는 사전순으로 오름차순으로 출력합니다. 입력 4 2 출력 1 2 1 3 1 4 2 3 2 4 3 4 조합 뽑는 방법은 외워두자 DFS(L ,S) 형태일때 else문이 조금 독특하게 생겻다, DFS(0, 1) 부터 시작 else { for (int i = S; i 2023. 8. 25.
수열 추측하기 ! 다시 풀어보기 가장 윗줄에 1부터 N까지의 숫자가 한 개씩 적혀 있다. 그리고 둘째 줄부터 차례대로 파스칼의 삼각형처럼 위의 두개를 더한 값이 저장되게 된다. 예를 들어 N이 4 이고 가장 윗 줄에 3 1 2 4 가 있다고 했을 때, 다음과 같은 삼각형이 그려진다. N과 가장 밑에 있는 숫자가 주어져 있을 때 가장 윗줄에 있는 숫자를 구하는 프로그램을 작성하시오. 단, 답이 여러가지가 나오는 경우에는 사전순으로 가장 앞에 오는 것을 출력하여야 한다. 예시 입력 4 16 예시 출력 3 1 2 4 이항계수, 순열, 조합을 이용해서 푸는 문제 숫자 4개로 햇을때 삼각형의 맨 위에서부터 3c0 3c1 3c2 3c3 형태로 이항계수로 이루어진다 구해둔 이항계수를 배열에 저장하고 dfs를 돌면서 순열을 구해서 .. 2023. 8. 25.
순열 구하기 10이하의 N개의 자연수가 주어지면 이 중 M개를 뽑아 일렬로 나열하는 방법을 모두 출력 입력 3 2 3 6 9 출력 3 6 3 9 6 3 6 9 9 3 9 6 앞에 중복순열 뽑는것과 비슷하지만 ch배열을 이용해서 이미 사용한 것은 사용하지 않게 해준다 import java.util.*; public class Main{ static int n, m; static int[] arr, ch, res; public void dfs(int L) { if(L == m){ for (int x : res) System.out.print(x + " "); System.out.println(); } else { for (int i =0; i < n; i++){ if (ch[i] == 0){ ch[i] = 1; res[.. 2023. 8. 24.
조합 구하기(메모리제이션) nCr = (n-1)C(r-1) + (n-1)C(r) 조합공식을 이용해서 조합 값 구하기 nCr에서 n=r이나 r이 0이되면 1을 리턴하니 dfs로 구하는 코드를 짜면 public int dfs(int n, int r){ //nCr에서 n=r이나 r이 0이면 1 if (n == r || r == 0) return 1; else return dfs(n-1,r-1) + dfs(n-1,r); } 코드는 간단하지만 숫자가 커지면 너무 비효율적이다 계산 결과를 저장해뒀다가 쓰는 메모리제이션으로 계산 결과가 같은 건 저장해둬서 효율적으로 써보자 public int dfs(int n, int r){ // 이미 nCr할 값을 구해서 배열에 저장해뒀으면 if (ch[n][r] > 0 ) return ch[n][r]; /.. 2023. 8. 24.
동전 교환 다음과 같이 여러 단위의 동전들이 주어져 있을때 거스름돈을 가장 적은 수의 동전으로 교환해주려면 어떻게 주면 되는가? 각 단위의 동전은 무한정 쓸 수 있다. 입력 3 1 2 5 15 출력 3 dfs 기존까지 해오던 방식 + 최적화를 해야 하는 문제 배열을 내림차순으로 받기 위해서 Array.sort(arr, Collections.reverseOrder()) 형태로 정렬할때 배열은 int형이 아니라 Integer 객체 배열 형태로 받아줘야 한다. 입력받은 배열을 1, 2, 5 순서로 하면 dfs를 상당히 많이 해야 되서 오류가 나기에 배열을 뒤집어 sum에 큰 숫자부터 들어가게 만들어줬다, 그리고 구한 횟수보다 더 깊이 dfs가 들어가면 어차피 정답이 안되기에 더 많은 횟수로 dfs하는 것도 제외한다 im.. 2023. 8. 24.
DFS 중복순열 1부터 N까지 번호가 적힌 구슬이 있습니다. 이 중 중복을 허락하여 M번을 뽑아 일렬로 나열 하는 방법을 모두 출력합니다. 입력 3 2 출력 1 1 1 2 1 3 2 1 2 2 2 3 3 1 3 2 3 3 dfs 중복순열 배열을 만들고 for문을 돌면서 배열[level]번째에 i를 넣어줌 else문 안에서도 n가닥으로 나가니 for문으로 n번 dfs를 해 준다 과정을 잘 모르겠으면 트리랑 스택을 그려서 판단해보자 import java.util.*; public class Main{ static int[] arr,res; static int timeLimit = 0; public void dfs(int v){ if (v == res.length){ for (int i = 0; i < res.length; .. 2023. 8. 24.
최대점수 구하기 현수는 선생님이 주신 N개의 문제를 풀려고 합니다. 각 문제는 그것을 풀었을 때 얻는 점수와 푸는데 걸리는 시간이 주어지게 됩니다. 제한시간 M안에 N개의 문제 중 최대점수를 얻을 수 있도록 해야 합니다. (해당문제는 해당시간이 걸리면 푸는 걸로 간주한다, 한 유형당 한개만 풀 수 있습니다.) 입력 출력 5 20 41 10 5 25 12 15 8 6 3 7 4 전, 전전문제와 비슷한 부분집합 합 구하기 문제, 조건에 시간제한도 더해주면서 bfs를 한다 import java.util.*; public class Main{ static int[] times, score; static int max = Integer.MIN_VALUE, timeLimit = 0; public void dfs(int v, int.. 2023. 8. 23.
바둑이 승차 철수는 그의 바둑이들을 데리고 시장에 가려고 한다. 그런데 그의 트럭은 C킬로그램 넘게 태울수가 없다. 철수는 C를 넘지 않으면서 그의 바둑이들을 가장 무겁게 태우고 싶다. N마리의 바둑이와 각 바둑이의 무게 W가 주어지면, 철수가 트럭에 태울 수 있는 가장 무거운 무게를 구하는 프로그램을 작성하세요. 입력 첫 번째 줄에 자연수 C(1 2023. 8. 23.
합이 같은 부분집합 N개의 원소로 구성된 자연수 집합이 주어지면, 이 집합을 두 개의 부분집합으로 나누었을 때 두 부분집합의 원소의 합이 서로 같은 경우가 존재하면 “YES"를 출력하고, 그렇지 않으면 ”NO"를 출력하는 프로그램을 작성하세요. 둘로 나뉘는 두 부분집합은 서로소 집합이며, 두 부분집합을 합하면 입력으로 주어진 원래의 집합이 되어 합니다. 예를 들어 {1, 3, 5, 6, 7, 10}이 입력되면 {1, 3, 5, 7} = {6, 10} 으로 두 부분집합의 합이 16으로 같은 경우가 존재하는 것을 알 수 있다. 내 풀이 부분집합을 dfs로 구한 게 배열합의 절반이면 되는거 아닌가? 라고 생각해서 구해봤는데 테스트 케이스에서 걸리는 게 있었고 원인을 찾지 못했다.. import java.util.*; public.. 2023. 8. 23.
그래프 최단거리(BFS) 위 그래프를 bfs로 탐색해 1번 정점에서 각 정점으로 가는 최단거리를 구해보자 2 : 3 3 : 1 4 : 1 5 : 2 6 : 2 이렇게 결과가 나오면 된다 레벨 탐색과 배열을 이용해서 탐색하는 방법이 있다 배열을 이용해서 탐색하는 방법 dis 배열을 만들어서 1번정점에서 n번 정점으로 가는데 걸리는 횟수를 기록한다 dis[nv]는 dis[v]의 다음 정점이니, dis[nv] = dis[cv]+1로 구할 수 있다 이렇게 구한 dis 배열을 출력하면 된다 public void bfs(int v){ ch[v] = 1; //시작하는 위치니까 거리는 0 dis[v] = 0; Queue q = new LinkedList(); q.offer(v); while (!q.isEmpty()){ int cv = q.po.. 2023. 8. 18.
경로 탐색(DFS, 인접리스트, ArrayList) 위 그림같은 방향 그래프를 1번부터 시작해서 5번까지 가는 방법의 갯수를 구해보자 인접행렬은 for문, 인접리스트는 foreach문을 사용, 인접리스트 처음에 생성할때 i = 0; i 2023. 8. 17.
말단 노드까지의 가장 짧은 경로 이진트리에서 루트 노드에서 말단 노드까지의 거리 중 제일 짧은 거리를 구하는 문제 노드 1~5가 있을때 트리가 완전이진트리가 아닌 상태 DFS로 구해보면 노드 클래스를 만들고 위의 그림대로 루트,lt,rt를 설정해준다 루트 노드에서 아래로 뻗어가는 레벨이 제일 작은 노드를 구하기 위해서 dfs 함수에 인자로 레벨을 전달해줘서 lt,rt가 모두 없으면 리턴을, 아니면 레벨을 증가시킨 dfs 함수를 재귀로 반복해 lt와 rt의 레벨 중 작은 것을 리턴해준다 public int dfs(int L, Node root){ //트리의 마지막 노드면 노드의 레벨을 리턴 if(root.lt == null && root.rt == null) return L; //Math.min으로 하면 dfs로 재귀를 돌다가 더 작은 .. 2023. 8. 16.
송아지 찾기(BFS) 현수의 위치와 송아지의 위치가 수직선상의 좌표 점으로 주어지면 현수는 현재 위치에서 송아지의 위치까지 다음과 같은 방법으로 이동한다. 송아지는 움직이지 않고 제자리에 있다. 현수는 스카이 콩콩을 타고 가는데 한 번의 점프로 앞으로 1, 뒤로 1, 앞으로 5를 이동할 수 있다. 최소 몇 번의 점프로 현수가 송아지의 위치까지 갈 수 있는지 구하는 프로그램을 작성하세요. 최소 - bfs를 이용해서 푸는 문제일 확률이 높다 bfs - 최단 거리를 구하는 알고리즘 앞, 뒤, 앞으로 많이 3가지 경우를 bfs로 풀어가며 체크 배열을 사용해서 그 값을 이미 방문한 적이 있는지 확인한다 while문의 내부에서는 처음 노드의 값을 꺼낸 후 큐의 길이만큼 for문을 돌면서 큐에 맨 앞 요소를 꺼내고 그거에 이동 가능한 좌.. 2023. 8. 15.
레벨 탐색(BFS) 레벨탐색 한 단계씩 탐색하는 방법 큐를 이용해서 레벨 탐색 BFS 함수 안에 노드를 담을 큐를 만들고 큐에가 비어있지 않는 동안 도는 while 반복문 안에 큐의 길이만큼 for문을 돌면서 연결된 노드를 출력, for문이 끝나면 레벨을 증가시킴 import java.util.*; class Node{ int data; Node lt, rt; public Node(int val) { data=val; lt=rt=null; } } public class Main{ Node root; public void BFS(Node root){ Queue Q=new LinkedList(); Q.add(root); int L=0; while(!Q.isEmpty()){ int len = Q.size(); System.out.. 2023. 8. 15.
부분집합 구하기(DFS) 자연수 n을 입력하면 1~n까지 원소를 갖는 부분집합을 출력하기 이진 트리 구조로 간 곳은 체크하면서 n+1에 도달하면 체크된 곳을 출력하기 왼쪽은 해당 인덱스를 체크하고 오른쪽은 체크하지 않으면서 진행한다 먼저 전역변수로 방문할 배열의 크기와 배열 방문 여부를 체크할 배열을 만들고 dfs 함수에서 n+1에 도달하면 방문 체크가 된 곳을 출력하고 아니면 왼쪽은 체크한 후 재귀, 오른쪽은 체크를 하지 않고 순회하게 만들어준다 public void DFS(int L){ //끝까지 왔으면 체크된 원소를 출력 if(L == n+1){ for(int i =1; i < L; i++){ if(ch[i] == 1) System.out.print(i + " "); } System.out.println(); } else .. 2023. 8. 15.
이진트리순회(DFS) 이진트리를 깊이우선탐색으로 돌때 전위, 중위, 후위 순회 3가지가 있다 1 2 3 4 5 6 7 으로 된 7개 노드가 있을떄 전위순회 부 - 왼 - 오 1 2 4 5 3 6 7 중위순회 왼 - 부 - 오 4 2 5 1 6 3 7 후위순회 왼 - 오 - 부 4 5 2 6 7 3 1 이 순서로 돈다 코드로 구현할 때는 Node 클래스와 Node 클래스를 재귀적으로 순회할 함수 2개를 만든다 class Node{ int data; Node lt, rt; //노드 생성자 public Node(int val) { data=val; //처음 생성시 좌우 노드는 null lt=rt=null; } } 데이터와 양쪽에 노드를 가지는 노드 클래스를 만들고 처음에 좌우 노드는 null로 만든다 public void DFS(.. 2023. 8. 15.
피보나치 수열 첫번째와 두번째는 1 세번째부턴 fib(n-1) + fib(n-2) 형태 그냥 재귀로 구현하면 효율이 많이 떨어진다 public int dfs(int n){ if(n == 1) return 1; else if(n == 2) return 1; else return dfs(n-1) + dfs(n-2); } 개선을 위해 메모리제이션(한번 사용한 값을 기억) 해두기 배열을 선언하고 dfs 함수를 사용하면 배열 해당 인덱스에 피보나치의 값이 들어가게 한다, 이미 그 값이 있으면 재귀를 하지 않고 배열 값을 리턴한다 if(fib[n] > 0 ) return fib[n]; if(n == 1) return fib[n] = 1; else if(n == 2) return fib[n] = 1; else{ return fib.. 2023. 8. 14.
팩토리얼 0까지 가면 *0으로 0이나 나와버리니까 1까지 갔을때 1 리턴 1 리턴하고 나서 dfs(2)의 2 리턴해서 1*2*3*4*5 형태로 다 출력된다 import java.util.*; class Main { public int dfs(int n){ if(n == 1) return 1; else { return n*dfs(n-1); } } public static void main(String[] args) { Main T = new Main(); Scanner in = new Scanner(System.in); int n = in.nextInt(); System.out.println(T.dfs(n)); } } 2023. 8. 14.
이진수 출력 10진수를 2진수로 바꾸는 방법 - 10진수를 더 이상 안나눠질때까지 2로 나누고 나머지를 거꾸로 출력하면 된다 11은 2진수로 1011 푸는 방법 재귀로 n/2 하면서 n이 0이 될때까지 탐색하고 n%2를 리턴한다 import java.util.*; class Main { public void dfs(int n){ if (n == 0) return; else { dfs(n / 2); System.out.print(n % 2 + " "); } } public static void main(String[] args) { Main T = new Main(); Scanner in = new Scanner(System.in); int n = in.nextInt(); T.dfs(n); } } 2023. 8. 14.
재귀함수(스택 프레임) n을 입력하면 1부터 n까지 출력해보자 반복문으로 스택에 차곡차곡 쌓아서 출력한다 함수 내부에 if, else로 리턴을 언제할지 잘 정의해두자 먼저 print로 출력하면 3 2 1 순서로 나오고 먼저 재귀를 돌면 3 2 1 0 까지 갓다가 0 리턴 1 리턴 2리턴 3 리턴 하면서 1 2 3 출력한다 if (n == 0) return; else { dfs(n-1); System.out.print(n + " "); } import java.util.*; class Main { public void dfs(int n){ if (n == 0) return; else { dfs(n-1); System.out.print(n + " "); } } public static void main(String[] args) .. 2023. 8. 14.
정렬, 이분검색,좌표 정리 정렬,이분검색,좌표 강의를 들으면서 알게 된 것 정리 Arrays.stream(arr).sum(); 2023. 8. 14.
마구간 정하기(결정 알고리즘) N개의 마구간이 수직선상에 있습니다. 각 마구간은 x1, x2, x3, ......, xN의 좌표를 가지며, 마구간간에 좌표가 중복되는 일은 없습니다. 현수는 C마리의 말을 가지고 있는데, 이 말들은 서로 가까이 있는 것을 좋아하지 않습니다. 각 마구간에는 한 마리의 말만 넣을 수 있고, 가장 가까운 두 말의 거리가 최대가 되게 말을 마구간에 배치하고 싶습니다. C마리의 말을 N개의 마구간에 배치했을 때 가장 가까운 두 말의 거리가 최대가 되는 그 최대값을 출력하는 프로그램을 작성하세요. 이분검색을 이용한 결정 알고리즘으로 푸는 문제 현재 인덱스의 마구간의 위치 - 이전 마구간의 위치가 mid 값 보다 크면 가능한 경우 lt와 rt는 각각 1과 끝 마구간으로 잡고 시작한다, lt를 처음 마구간으로 잡으면.. 2023. 8. 14.