본문 바로가기
피자 배달 거리 !문제 다시 풀어보기 9/3.. 조합 만드는 방식은 외워두자.. 피자집 ArrayList, 집위치 ArrayList를 만들고 피자집 m개를 고른 조합을 만든다 각 집까지의 최소 배달 거리를 sum에 누적해서 가장 작은 경우가 나오는 조합일때 정답 보드를 만드는게 아니라 입력 받을 때 피자집인지 가정집인지 판단해서 ArrayList에 넣는다 DFS에서는 만든 조합으로 가정집을 각각 돌면서 한 가정집까지 가는 최소거리를 구하고 그걸 sum에 누적한다 전체 코드 import java.util.*; class point{ int x; int y; point(int x, int y){ this.x = x; this.y = y; } } class Main{ static int[] comb; //조합 저장용 배열 s.. 2023. 9. 3.
섬나라 아일랜드(BFS) 풀이에 Pointer 클래스를 사용한 것 이외에는 거의 비슷하다 import java.util.*; class Pointer{ int x; int y; Pointer(int x, int y){ this.x = x; this.y = y; } } class Main{ static int[] dx = {-1,0,1,0,-1,-1,1,1}; static int[] dy = {0,1,0,-1,-1,1,1,-1}; static int[][] board; static Queue Q = new LinkedList(); static int res = 0, n; public void Solution(){ for (int i = 0; i < n; i++){ for (int j = 0; j < n; j++){ if (boar.. 2023. 9. 3.
섬나라 아일랜드(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.
조합 구하기 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.