728x90

최솟값 만들기

https://school.programmers.co.kr/learn/courses/30/lessons/12941

스크린샷 2022-09-22 오후 5 55 22


문제 설명

길이가 같은 배열 A, B 두개가 있습니다. 각 배열은 자연수로 이루어져 있습니다.
배열 A, B에서 각각 한 개의 숫자를 뽑아 두 수를 곱합니다. 이러한 과정을 배열의 길이만큼 반복하며, 두 수를 곱한 값을 누적하여 더합니다. 이때 최종적으로 누적된 값이 최소가 되도록 만드는 것이 목표입니다. (단, 각 배열에서 k번째 숫자를 뽑았다면 다음에 k번째 숫자는 다시 뽑을 수 없습니다.)

예를 들어 A = [1, 4, 2] , B = [5, 4, 4] 라면

  • A에서 첫번째첫 번째 숫자인 1, B에서 첫 번째 숫자인 5를 뽑아 곱하여 더합니다. (누적된 값 : 0 + 5(1x5) = 5)
  • A에서 두번째 숫자인 4, B에서 세 번째 숫자인 4를 뽑아 곱하여 더합니다. (누적된 값 : 5 + 16(4x4) = 21)
  • A에서 세번째 숫자인 2, B에서 두 번째 숫자인 4를 뽑아 곱하여 더합니다. (누적된 값 : 21 + 8(2x4) = 29)

즉, 이 경우가 최소가 되므로 29를 return 합니다.

배열 A, B가 주어질 때 최종적으로 누적된 최솟값을 return 하는 solution 함수를 완성해 주세요.


제한사항

  • 배열 A, B의 크기 : 1,000 이하의 자연수
  • 배열 A, B의 원소의 크기 : 1,000 이하의 자연수

입출력 예

A B answer
[1, 4, 2] [5, 4, 4] 29
[1,2] [3,4] 10

풀이

길이가 같은 두개의 배열이 주어지고 두 배열의 원소를 서로 곱해서 answer이라는 변수에 누적 저장해서 answer 값이 최소가 되는 값을 구하면 되는 문제이다. A, B를 오름차순으로 정렬하면 A는 1, 2, 4가 되고 B는 4, 4, 5가 된다. A에서 오름차순으로 선택하면 1 B에서 큰 수부터 선택하면 5 두 수를 곱해주면 0 + ( 1 * 5 ) = 5 -> 5 + ( 2 * 4) = 13 -> 13 + (4 * 4) = 29가 된다.


코드

import java.util.*;
class Solution
{
    public int solution(int []A, int []B)
    {
        int answer = 0;
        Arrays.sort(A);  // 두 배열을 정렬 해준다.
        Arrays.sort(B);

        for(int i = 0; i < A.length; i++) {
            answer = answer + (A[i] * B[A.length - 1 - i]);  // a는 오름차순으로 선택하고 b는 큰 수 부터 선택헤서 곱해준다.
        }
        return answer;
    }
}

JadenCase 문자열 만들기

(문제 설명 혹은 링크)
https://school.programmers.co.kr/learn/courses/30/lessons/12951

스크린샷 2022-09-23 오후 4 28 38


문제 설명

JadenCase란 모든 단어의 첫 문자가 대문자이고, 그 외의 알파벳은 소문자인 문자열입니다. 단, 첫 문자가 알파벳이 아닐 때에는 이어지는 알파벳은 소문자로 쓰면 됩니다. (첫 번째 입출력 예 참고)
문자열 s가 주어졌을 때, s를 JadenCase로 바꾼 문자열을 리턴하는 함수, solution을 완성해주세요.


제한 조건

  • s는 길이 1 이상 200 이하인 문자열입니다.
  • s는 알파벳과 숫자, 공백문자(" ")로 이루어져 있습니다.
    • 숫자는 단어의 첫 문자로만 나옵니다.
    • 숫자로만 이루어진 단어는 없습니다.
    • 공백 문자가 연속해서 나올 수 있습니다.

입출력 예

s return
"3people unFollowed me" "3people Unfollowed Me"
"for the last week" "For The Last Week"

풀이

이 문제를 봤을 때 비교적 간단한 문제라고 생각하고 풀었습니다. 하지만 문제를 제대로 읽지 않은 탓에 엄청 헤맸습니다. 우선 공백 문자를 보자마자 String []str = s.split(" "); 으로 잘랐습니다. 잘못된 풀이로 풀었을 때 substring(0, 1)을 이용해서 첫 번째 문자를 구하고 toUpperCase()를 이용해 첫 번째 문자를 대문자로 변환해 주었습니다. 또한 substring(1, str[i].length()).toLowerCase()를 이용해서 첫 번째 문자를 제외하고 변환하여 더하였습니다. 하지만 answer를 더해주는 과정에서 마지막 문자열에 공백 문자가 포함됩니다. 따라서 원래 문자열 마지막이 공백일 경우와 아닐 경우에 대한 코드를 작성하였습니다. 하지만 제한 조건에 공백 문자가 연속해서 나올 수 있다는 것을 보고 다시 문제를 풀었습니다. 모든 문자열 소문자로 변경하고 첫 번째 글자인지 판단하는 boolean 변수를 추가해 주었습니다. 문자열만큼 반복해서 for문을 수행하고 만약 공백이 나오면 isFirst를 true로 변경하고 아니면 false를 수행한다. 만약 isFirst가 true일 경우 대문자로 변경한다.


잘못된 코드

public class JadenCase {
    public static void main(String[] args) {
        String s = "for the last week ";
        String []str = s.split(" "); // 공백을 기준으로 문자열 자르기
        String answer = "";

        // 공백을 기준으로 잘려진 문자열의 수만큼 반복
        for(int i = 0; i < str.length; i++) {
            if(str.length == 0) {
                answer += " ";
            }
            else {
                answer += str[i].substring(0, 1).toUpperCase(); // 단어 첫번째 대문자로 변환하여 더하기
                answer += str[i].substring(1, str[i].length()).toLowerCase(); // 첫글자를 제외하고 소문자로 변환하여 더하기
                answer += " "; // 띄어쓰기
            }
        }
        //원래 문자열 마지막이 공백일 경우 그대로 answer 반환
                if(s.substring(s.length() -1, s.length()).equals(" ")) {
               System.out.println(answer);
                }
                //마지막에 공백이 더해져서 그 공백을 제외한 answer값 반환
                else {
              answer = answer.substring(0, answer.length() - 1);
              System.out.println(answer);
                }
    }
}

정확한 코드

class Solution {
    public String solution(String s) {
        String answer = "";
         // 모든 문자열 소문자로 변경
        String[] srr = s.toLowerCase().split("");

        boolean isFirst = true; // 첫번째 글자인지 판단 
        // 문자열 만큼 반복
        for(int i = 0; i < srr.length; i++) {
            // 첫 글자일 경우 대문자로 변경
            if(isFirst) {
                answer += srr[i].toUpperCase(); 
            }
            else {
                answer += srr[i];
            }
            // 공백이 나오면 첫 글자 true로 변경
            if(srr[i].equals(" ")) {
                isFirst = true;
            }
            else {
                isFirst = false;
            } 
        }
        return answer;
    }
}

 

728x90

'알고리즘 > 알고리즘 문제풀이' 카테고리의 다른 글

LeetCode Valid Parentheses, Merge Two Sorted Lists  (0) 2022.10.03
백준) DP, DFS  (0) 2022.08.27
백준) HashMap  (0) 2022.07.23
백준) BFS, 다익스트라  (0) 2022.07.19
백준) 우선순위 큐, DP  (0) 2022.07.18
728x90

수익 4097번


내가 떠올린 풀이 해설

입력이 많지 않아 BufferedReader보단 Scanner를 사용했습니다. 처음 코드를 작성했을 때 max 값을 0으로 선언을 해주었지만 입력값이 음수일 경우 max 값을 구할 때 max 값이 0이 되므로 max 값을 Integer.MIN_VALUE로 선언해 주어야 합니다. 총수입을 담을 sum 변수를 만들었습니다. 입력의 마지막은 0으로 구분해서 입력 n이 0이면 break 하고 0이 아니면 for 문으로 n 미만까지 for 문을 수행한다. for 문에는 입력 값을 담을 num을 선언해 주었고 입력받은 값을 sum에 누적해서 더합니다. Math.max를 이용해 max와 sum을 비교해 큰 값을 max에 담았습니다. sum의 값이 음수가 되면 sum 값을 0으로 다시 초기화하였습니다.


정확한 풀이

import java.util.*;
public class Baek4097 {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		while(true) {
			int n = sc.nextInt();
			int max = Integer.MIN_VALUE; 
			int sum = 0;
			if(n == 0) {
				break;
			}
			else {
				for(int i = 0; i < n; i++) {
					int num = sc.nextInt();
					sum += num;                // -3, 1, 10, 8, 3, 11
					max = Math.max(max, sum);  // 0, 1, 10, 10, 10, 11
					if(sum < 0) {
						sum = 0;
					}
				}
				System.out.println(max);
			}
		}
	}
}

풀이 2

문제 분류가 다이나믹 프로그래밍이어서 DP로 풀어보려 했는데 방법이 떠오르지 않아 DP를 이용해서 푼 풀이를 가져왔습니다. 위의 코드와 차이점은 배열을 이용해서 현재 i의 값과 직전 값과 현재 i의 값을 더한 게 더 클 때 arr[i]의 값을 직전 값과 현재 i의 값으로 바꿔주는 것입니다. DP의 메모리제이션을 이용해서 해결한 것 같습니다.
https://velog.io/@pss407/%EB%B0%B1%EC%A4%804097-%EC%88%98%EC%9D%B5

 

[백준]#4097 수익

문제연종이는 창업했다. 오늘은 창업한지 N일이 되었고, 매일 매일 수익을 적어놓았다.어느 날 연종이는 가장 많이 돈을 번 구간이 언제인지 궁금해졌다.오늘이 창업한지 6일 되었고, 수익이 다

velog.io


정확한 풀이

import java.util.*;

public class Baek4097 {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		while(true) {
			int n = sc.nextInt();
			int max = Integer.MIN_VALUE;
			int sum = 0;
			int[] arr = new int[n];
			if(n == 0) {
				break;
			}
			else {
				for(int i = 0; i < n; i++) {
				        int x = sc.nextInt();
	                                arr[i] = x;
                                        if(i > 0) {
	                                       int y = arr[i-1];
                                               if(x + y > x) {   //직전 값과 현재 i의 값을 더한게 더 클 때
	                                          arr[i] = x + y;
                                               }
	                                 }
	                         }
	                         max = Math.max(max, arr[i]);
			}
			System.out.println(max);
		}
	}
}

단지 번호 붙이기 2667번


내가 떠올린 풀이 해설

상하좌우를 탐색할 int 배열 dx, dy를 선언합니다. 지도 크기를 입력받을 n, 2차원 배열의 map, DFS의 visit 배열, 총 단지 수를 구하기 위한 total, 각 단지에 속하는 집의 수를 구하기 위해 cnt를 선언해 주었습니다. BufferedReader를 이용해 입력을 받았습니다. map의 입력은 split를 이용해 잘라서 map의 2차원 배열에 넣어 주었습니다.(split("")[i]의 참고 자료: https://crazykim2.tistory.com/549) 전체 map을 탐색하기 위해 이중 for 문을 이용하였고 map의 (i, j)가 1이고 방문하지 않았다면 총 단지 수와 cnt의 수를 늘려주고 DFS를 호출합니다. DFS에서는 상하좌우 탐색을 진행하면서 cnt를 늘려줍니다. 마지막으로 cnt의 값을 List에 담아줍니다. 각 단지 내 집의 수를 오름차순으로 정렬하여 출력해 주어야 하므로 Collections.sort()를 이용해 정렬하였습니다.


정확한 풀이

import java.util.*;
import java.io.*;
public class Baek2667 {
	static int[] dx = {1, 0 ,0, -1};
	static int[] dy = {0, 1, -1, 0};
	static int n; // 지도 크기 
	static int[][] map;
	static boolean[][] visit;
	static int total = 0;  // 총 단지 수 
	static int cnt;
	static List<Integer> cnts = new ArrayList<>(); // 각 단지에 속하는 집의 수 
	
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		n = Integer.parseInt(br.readLine());
		map = new int[n][n];
		visit = new boolean[n][n];
		
		String str;
		for(int i = 0; i < n; i++) {
			str = br.readLine();
			for(int j = 0; j < n; j++) {
				map[i][j] = Integer.parseInt(str.split("")[j]);
			}
		}
		for(int i = 0; i < n; i++) {
			for(int j = 0; j < n; j++) {
				cnt = 0;
				if(map[i][j] == 1 && !visit[i][j]) {
					total++;
					cnt++;
					dfs(i, j);
					cnts.add(cnt);
				}
			}
		}
		System.out.println(total);
		Collections.sort(cnts);
		for(int i = 0; i < cnts.size(); i++) {
			System.out.println(cnts.get(i));
		}
	}

	private static void dfs(int i, int j) {
		visit[i][j] = true;
		for(int k = 0; k < 4; k++) {
			int nx = dx[k] + i;
			int ny = dy[k] + j;
			if(nx >= 0 && nx < n && ny >= 0 && ny < n) {
				if(!visit[nx][ny] && map[nx][ny] == 1) {
					cnt++;
					dfs(nx, ny);
				}
			}
		}
	}
}

오늘의 회고

요즘 스터디와 공모전으로 너무 바빠서 코딩 테스트 문제를 풀지 못했더니 많이 까먹은 것 같습니다. 이제 곧 하반기 채용 시작인데 다시 코딩 테스트 공부를 좀 해야겠습니다. 알고리즘 너무 어려워 이번에 알고리즘 스터디에 참여하게 되었는데 다들 실력이 좋으셔서 놀랐습니다. 분발하자

728x90
728x90

숨바꼭질 1679번


내가 떠올린 풀이 해설

BFS를 응용해서 푸는 문제였다. BFS()를 호출한 후 BFS에서 arr 배열을 최대 크기 배열로 생성한 후 Queue에 n을 add한다. Queue가 비어있을 때까지 반복한다. now 값에 Queue에서 poll 한 값을 대입하고 for문을 i가 3보다 작을 때까지 반복한다. 1초 후에 now - 1, now + 1, now * 2로 움직여야한다. 만약 next가 k와 같다면 arr[now]를 리턴해준다. 또한 만약 next가 0보다 크거나 같고 next가 100001보다 작아야하고 arr[next]가 0일 때 arr[next]에 arr[now] + 1을 대입한다. 그리고 Queue에 next를 add한다.


정확한 풀이

import java.util.*;
public class Baek1697 {
	static int n;
	static int k;
	static int[] arr;
	static Queue<Integer> que = new LinkedList<>();
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		n = sc.nextInt();
		k = sc.nextInt();
		
		if (n >= k) {
            System.out.println(n - k);
        } else {
            System.out.println(BFS());
        }
	}
	private static int BFS() {
		arr = new int[100001];
		que.add(n);
		arr[n] = 1;
		while(!que.isEmpty()) {
			int now = que.poll();
			for(int i = 0; i < 3; i++) {
				int next;
				if (i == 0) {
                    next = now - 1;
                } 
				else if (i == 1) {
                    next = now + 1;
                } 
                else {
                    next = now * 2;
                }
                if (next == k) {
                    return arr[now];
                }
                if (next >= 0 && next < 100001 && arr[next] == 0) {
                    arr[next] = arr[now] + 1;
                    que.add(next);
                }
			}
		}
		return 0;
	}
}

파티 1238번


내가 떠올린 풀이 해설

이 문제를 푸는데 시간이 오래 걸렸다. 다익스트라에서 조금만 응용하면 되는 문제였다. 1~N을 출발점으로 파티 마을 X까지의 거리를 다익스트라로 구한다. 그리고 반대로 파티 마을 X를 출발점으로 다익스트라를 돌려서 각 마을까지의 거리를 구했다. 그리고 이 두 값을 마을마다 더해주면 오고 가는 거리가 나오는데 이 값들 중 최댓값을 구하면 된다. time 배열은 파티 마을까지 오고 가는 거리의 값이다. 1~N 마을을 출발지로 다익스트라를 돌린 후 X까지의 거리를 time에 더해준다. 그 후 X를 출발지로 각 마을까지 거리를 구하여 time에 더해준다. 그 이후 time의 값들 중 최대값을 출력한다. 그 다음 dijkstra를 호출하고 다익스트라 메서드에서 우선순위 큐에 시작 정점을 넣어준다. 시작 지점의 가중치는 0이다. visit, distance를 초기화하고 distance에는 -1을 넣어준다. 우선순위 큐가 빌 때까지 while문을 반복한다. 현재 정점에 방문하지 않았을 때 연결된 정점들에 대해 검사를 시작한다. 연결된 정점의 가중치가 -1이거나 연결된 정점의 가중치가 현재 정점의 가중치와 현재 간선의 가중치의 합보다 클 때 값을 업데이트한다. 업데이트 후 다음 정점을 우선순위 큐에 넣어준다. Circle 클래스는 정점의 번호와 가중치를 가진다. 우선순위 큐의 타입으로 이용하기 위해 Comparable을 implements 해준다. 정렬 기준은 가중치의 오름차순이다.


 

참고 블로그

https://jellyinghead.tistory.com/79

 

[백준 1238] 파티 (자바)

난이도 : 골드 3 다익스트라 알고리즘을 이용해 풀었습니다. 2020/11/02 - [문제풀이/자바] - [백준 1753] 최단경로 (자바) [백준 1753] 최단경로 (자바) https://www.acmicpc.net/problem/1753 1753번: 최단경로..

jellyinghead.tistory.com


정확한 풀이

import java.util.*;
import java.io.*;

public class Baek1238 {
	static int[] distance;
	static boolean[] visit;
	static ArrayList<Circle>[] list;
	static PriorityQueue<Circle> que = new PriorityQueue<>();
	
	public static void main(String[] args) throws IOException {
		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());
		int x = Integer.parseInt(st.nextToken());
		visit = new boolean[n + 1];
		list = new ArrayList[n + 1];
		distance = new int[n + 1];
		
		for(int i = 1; i <= n; i++) {
			list[i] = new ArrayList<Circle>();
		}
		
		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());
			list[u].add(new Circle(v, w));
		}
		int time[] = new int[n+1];
        for(int i = 1; i <= n; i++) {
            dijkstra(i);
            time[i] += distance[x];
        }
        
        dijkstra(x);
        for(int i = 1; i <= n; i++)
            time[i] += distance[i];
        
        int max = 0;
        for(int i = 1; i <= n; i++) 
            max = Math.max(max, time[i]);
    
        System.out.println(max);
	}

	private static void dijkstra(int x) {
		que.offer(new Circle(x, 0));
		visit = new boolean[visit.length];
		distance = new int[distance.length];
        Arrays.fill(distance, -1);
		distance[x] = 0;
		while(!que.isEmpty()) {
			Circle current = que.poll();
			int c_v = current.vertex;
			if(visit[c_v]) {
				continue;
			}
			visit[c_v] = true;
			for(int i = 0; i < list[c_v].size(); i++) {
				Circle tmp = list[c_v].get(i);
				int next = tmp.vertex;
				int value = tmp.value;
				if(distance[next] == -1 || distance[next] > distance[c_v] + value) {
					distance[next] = distance[c_v] + value;
					que.add(new Circle(next, distance[next]));
				}
			}
		}	
	}
}	
class Circle implements Comparable<Circle> {
	int vertex, value;
	Circle(int vertex, int value) {
		this.vertex = vertex;
		this.value = value;
	}
	@Override
	public int compareTo(Circle o) {
		return value - o.value;
	}
}

오늘의 회고

오늘은 BFS와 다익스트라 문제를 풀었습니다. 두 문제 모두 조금만 응용해서 푸는 문제였고, 너무 오랫만에 BFS와 다익스트라 문제를 풀어서 시간이 오래걸렸습니다. 다른 개념들도 까먹지않게 여러 개념의 문제들을 풀어야할 것 같습니다. 조금만 화이팅하자

728x90

'알고리즘 > 알고리즘 문제풀이' 카테고리의 다른 글

백준) DP, DFS  (0) 2022.08.27
백준) HashMap  (0) 2022.07.23
백준) 우선순위 큐, DP  (0) 2022.07.18
백준) 수학(피타고라스), 이분 탐색  (0) 2022.07.16
백준) 수학, 이분 탐색  (0) 2022.07.13
728x90

최대 힙 11279번


내가 떠올린 풀이 해설

이 문제는 단순히 우선순위 큐를 이용하면 해결할 수 있는 문제이다. 우선순위 큐의 Collections.reverseOrder를 이용하면 poll를 하면 배열에서 큰 숫자대로 출력된다. 0일 때 배열에서 제일 큰 수가 출력되도록 문제를 풀면 된다.


정확한 풀이

import java.util.*;
import java.io.*;
public class Baek11279 {

	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		int n = Integer.parseInt(br.readLine());
		PriorityQueue<Integer> que = new PriorityQueue<>(Collections.reverseOrder());
		for(int i = 0; i < n; i++) {
			int m = Integer.parseInt(br.readLine());
			if(m != 0) {
				que.offer(m);
			}
			else {
				if(que.isEmpty()) {
					System.out.println(0);
				}
				else {
					System.out.println(que.poll());
				}
			}
		}
	}
}

Four Squares 17626번


내가 떠올린 풀이 해설

dp는 점화식을 떠올리는게 제일 어렵다. 제일 작은 수부터 계산을 해보면 1은 1개, 2 2개, 3 3개, 4  1개, 5  2개, 6  3개, 7  4개, 8  2개, 9  1개이다. 어떤 수 i의 최적의 해는 i 보다 작은 모든 제곱수 들 중 i - (제곱수)를 한 해 중 가장 작은 해에 1을 더한 값을 의미합니다. 그러면 점화식은 dp [i] = min(dp [i - j * j]) + 1 이렇게 작성할 수 있다. 작성한 점화식을 이용해 2중 for문을 이용해 풀면 답이 나오는 문제이다.


정확한 풀이

import java.util.*;
public class Baek17626 {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		int[] dp = new int[n + 1];
		dp[1] = 1;
		int min = 0;
		// 점화식 dp[i] = min(dp[i - j * j]) + 1
		for(int i = 2; i <= n; i++) {
			min = Integer.MAX_VALUE;
			for(int j = 1; j * j <= i; j++) {
				int tmp = i - j * j;
				min = Math.min(min, dp[tmp]);
			}
			dp[i] = min + 1;
		}
		System.out.println(dp[n]);
	}
}

오늘의 회고

오늘은 한주를 시작하는 월요일입니다. 이번 주도 열심히 공부하고 알고리즘 문제를 풀겠습니다. 벌써 제가 5월 13일에 퇴사하고 취업 준비한 지 2달이 지났습니다. 아직 부족한 것이 많은데 시간이 금방 지나갔습니다. 원래 퇴사하고 그전에 있던 회사에서 느낀 점 퇴사한 이유 취업준비에 대한 다짐을 쓴 글을 취업 준비하기 첫날에 쓰려고 했는데 쓰고 지우 고를 반복하다가 아직까지 작성하지 못했습니다. 취업 준비한 지 2달쯤 지났고 해이해진 정신상태를 다시 잡기 위해 다음 주 까지는 작성하겠습니다.

728x90
728x90

87번 2 x n 타일링


내가 떠올린 풀이 해설

크기가 2 x 1일 때부터 2 x 2... 하나씩 높여가면서 경우의 수를 구하면 규칙이 나온다. 그 규칙을 이용해서 점화식을 구하면 되는 문제이다. 점화식은 arr [n] = arr[n - 1] + arr[n - 2]이다. arr배열을 채울 때마다 10,007으로 % 연산을 수행해야 한다. 


정확한 풀이

import java.util.*;
public class Baek11726 {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		long[] arr = new long[n + 1];
		arr[1] = 1;
		arr[2] = 2;
		int mod = 10007;
		for(int i = 3; i <= n; i++) {
			arr[i] = (arr[i - 1] + arr[i - 2]) % mod;
		}
		System.out.println(arr[n]);
	}
}

88번 쉬운 계단 수


내가 떠올린 풀이 해설

n번째 길이에서 5로 끝나는 계단 수가 있었을 때 이 계단 수의 n - 1의 자리에 올 수 있는 수는 1 차이가 나는 4와 6이다. 이를 이용해 문제를 풀겠다. arr[n][h] : 길이가 n인 계단에서 h 높이로 종료되는 계단 수를 만들 수 있는 경우의 수이다. n에서 계단 높이가 0일 때 계단 수가 되려면 n - 1에서는 높이가 1이어야 한다. n에서 계단 높이가 9일 때 계단 수가 되려면 n - 1 에서는 높이가 8이어야 한다. 나머지는 가운데 계단이므로 h + 1, h - 1 양쪽에서 계단 수를 만들 수 있다. 

 

높이에 따른 점화식

  •  arr[i][h] = arr[i - 1][h + 1] // h = 0
  • arr[i][h] = arr[i - 1][h - 1] // h = 9
  • arr[i][h] = arr[i + 1][h - 1] + arr[i - 1][h - 1] // h = 1 ~ 8

arr배열의 값을 초기화한다. 각 높이에서 길이가 1인 계단 수는 모두 1가지이므로 1로 초기화한다. 단, 0으로 시작될 수 없으므로 이때는 0으로 초기화한다. arr 배열을 채울 때마다 1000000000으로 % 연산을 수행한다. arr[n][0] ~ arr[n][9]의 모든 값을 더한 값을 출력한다 n = 2일 때 각 자릿수의 값을 모두 더하면 n = 2의 길이에서 만들 수 있는 모든 계단 수의 경우의 수를 출력할 수 있다.


정확한 풀이

import java.util.Scanner;

public class Baek10844 {

	public static void main(String[] args) {
		long mod = 1000000000;
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		long[][] arr = new long[n + 1][11];
		for(int i = 1; i <= 9; i++) {
			arr[1][i] = 1;
		}
		for(int i = 2; i <= n; i++) {
			arr[i][0] = arr[i - 1][1];
			arr[i][9] = arr[i - 1][8];
			for(int j = 1; j <= 8; j++) {
				arr[i][j] = (arr[i - 1][j - 1] + arr[i - 1][j + 1]) % mod;
			}
		}
		long sum = 0;
		for(int i = 0; i < 10; i++) {
			sum = (sum + arr[n][i]) % mod;
		}
		System.out.println(sum);
	}

}

오늘의 회고

오늘은 DP문제 2문제를 풀었습니다. 첫 번째 문제는 난이도가 높지 않은 문제였고, 두 번째 문제는 문제를 이해하는데 시간이 많이 걸렸습니다. 프로그래머스 교육도 진행 중이라 앞의 개념에 대해 까먹을 것 같습니다. 이제는 교육도 듣고 앞에 문제 개념도 복습하고 그 개념에 대한 문제를 푸는 식으로 공부를 진행해야 될 것 같습니다. 하면 할수록 저는 알고리즘이 어려운 것 같습니다. 알고리즘 잘하고 싶다. 꾸준히 공부하겠습니다.

728x90
728x90

step 1 - 4. 숫자 게임


내가 떠올린 풀이 해설

두 배열을 Arrays.sort를 이용해서 정렬을 하고 aIndex가 a 길이랑 같지 않고 bIndex가 B길이보다 같지 않게 반복분을 실행한다. 반복문 안에서 만약 A배열의 aIndex위치에 있는 수와 B배열의 bIndex위치에 있는 수를 비교했을 때 B가 더 크면 answer의 수를 늘려주고 aIndex의 수를 하나 늘려준다. if문 조건을 만족하지 않으면 bIndex의 수를 하나 늘려준다.


정확한 풀이

import java.util.*;
class Solution {
    public int solution(int[] A, int[] B) {
        int answer = 0;
        Arrays.sort(A);
        Arrays.sort(B);
        
        int aIndex = 0;
        int bIndex = 0;
        
        while(aIndex != A.length && bIndex != B.length) {
            if(A[aIndex] < B[bIndex]) {
                answer++;
                aIndex++;
            }
           bIndex++;
        }
        return answer;
    }
}

오늘의 회고

문제는 금요일에 풀었지만 블로그는 오늘 작성했습니다. 금요일에 친구들 중에 처음으로 결혼을 하는 친구가 있는데 신혼집에 들어가서 가구 조립이나 청소를 도와주었습니다. 행복하게 오래오래 살았으면 좋겠습니다. 이번 문제는 프로그래머스 1주 차 마지막 문제로 어렵지는 않은 문제였습니다. 프로그래머스에서 힌트를 주었는데 힌트에 맞춰서 코드를 작성하려다 보니 꼬여서 힌트 코드를 사용 안 하고 문제를 풀었습니다.

728x90
728x90

step 1 - 2. 가장 큰 수

 


내가 떠올린 풀이 해설

처음에 문제를 보았을 때 투 포인터로 전체를 탐색하면서 문자를 연결해서 숫자 형식으로 바꿔서 max값을 구해서 다시 String으로 바꿔서 출력을 하려고 했는데 실패했다. int형 배열을 String 배열로 바꾸고 Array.sort를 이용해서 정렬을 한다. 만약 전부 0이면 0000으로 나와서 0으로 된 배열만 예외 처리를 해준다.


정확한 풀이

import java.util.*;
import java.io.*;

class Solution {
    public String solution(int[] numbers) {
        String answer = "";
        String[] str = new String[numbers.length];
        for(int i = 0; i < numbers.length; i++) {
            str[i] = String.valueOf(numbers[i]);
        }
        Arrays.sort(str, new Comparator<String>() {
            @Override
            public int compare(String a, String b) {
                return (b + a).compareTo(a + b);
            }
        });
        if(str[0].equals("0")) {
            return "0";
        }
        else {
            for(int i = 0; i < str.length; i++) {
                answer += str[i];
            }
        }
        return answer;
    }
}

step 1 - 3. 예산


내가 떠올린 풀이

이분 탐색으로 해결하면 되는 문제였다. 근데 이분탐색을 푸는데 갑자기 머릿속이 꼬여서 엄청 헤매면서 풀었다. 정답도 100점 만점에 90점이다.


정확한 풀이

import java.util.*;
class Solution {
    public int solution(int[] budgets, int M) {
       int answer = 0;
        int sum = 0;
        Arrays.sort(budgets);
        for(int i = 0; i < budgets.length; i++) {
            sum += budgets[i];
        }
        int max = 0;
        if(sum >= M) {
        	int start = budgets[0];
            int end = budgets[budgets.length - 1];
            sum = 0;
            while(start <= end) {
                int midv = (start + end) / 2;
                sum = 0;
               //midv = 119 124 127
                for(int i = 0; i < budgets.length; i++) {
                    if(midv > budgets[i]) {
                        sum += budgets[i];
                    }
                    else {
                        sum += midv;
                    }
                }
                if(sum > M) {
                    end = midv - 1;  //end 129 
                }
                else {
                	start = midv + 1;
                	answer = midv;
                }  
            }
        }
        else {
            answer = budgets[budgets.length - 1];
        }
        return answer;
    }
}

오늘의 회고

오늘 문제를 풀면서 너무 헤맷습니다. 공부를 좀 더 열심히 해야 될 것 같습니다. 자신감이 떨어진 하루입니다.ㅠㅠ 좀 더 분발해서 공부하겠습니다. 중간고사도 있는데 중간고사 때 많이 못 풀 것 같은 느낌이.... 열심히 하겠습니다.

728x90
728x90

기지국 설치

입출력 예

N stations w return
11 [4, 11] 1 3
16 [9] 2 3

내가 떠올린 풀이 해설

while문으로 현재 있는 위치부터 n보다 작거나 같을 때까지 반복한다. while문 안에서 현재 위치가 모든 기지국의 범위를 넘어선 경우와(만약 idx가 기지국 위치 배열의 길이보다 작거나 같고) 또한 현재 위치가 기지국의 범위보다 작은 경우일 때(현재 위치가 기지국 위치와 전파를 뺐을 때 보다 작으면) 기지국을 설치해준다. 그리고 현재 위치를 기지국의 전파 곱하기 2 더하기 1을 하고 현재 위치를 더해준다. 이는 설치한 기지국의 위치에서 벗어난 곳으로 위치해주기 위해서이다. 또한 위의 if문에 만족을 못하면 현재 위치가 모든 기지국의 범위보다 작으며 특정 기지국에 범위 내에 있는 경우이므로 현재 위치를 기지국의 파장의 범위 밖으로 옮기고 기지국의 위치도 옮겨준다.


정확한 풀이

class Solution {
    public int solution(int n, int[] stations, int w) {
        int answer = 0;
        int now = 1;
        int idx = 0;
        while(now <= n) {
            if(idx >= stations.length || now < stations[idx] - w) {
                answer++;
                now = (w * 2 + 1) + now;
            }
            else {
                now = stations[idx] + w + 1;
                idx++;
                
            }
        }
        return answer;
    }
    
}

오늘의 회고

프로그래머스로 처음 풀어본 문제였습니다. 커뮤러닝을 통해 예전에 배운 개념을 복습하는 식으로 진행이 될 것 같아 만족합니다. 또한 다른 사람들의 코드를 리뷰해주고 제 코드도 리뷰받는 방식으로 진행이 되어서 코딩 테스트뿐만 아니라 코드를 짜는 실력도 같이 성장할 것 같습니다. 열심히 공부하겠습니다. 오늘 문제 풀어보니까 아직 많이 부족한데 이 과정을 통해 한층 더 성장하는 제가 되었으면 좋겠습니다.

728x90

+ Recent posts