import java.util.Arrays;

public class Solution {
	
	// 요격 시스템
	
	public static int solution(int[][] targets) {
		int answer = 0;
		
		// 개구간 (s, e)로 표현되는 폭격 미사일을 s와 e에서 발사하는 요격 미사일로는 요격할 수 없기 때문에 각각의 원소에 10을 곱한 후
		// 첫 번째 원소에서는 +1을, 두 번째 원소에서는 -1을 하여 폐구간 [r, f]을 만든 후 [Java] 프로그래머스 [Level-3] 단속카메라 문제처럼 풀도록 한다.
		int[][] tempTargets = new int[targets.length][targets[0].length];
		
		for (int i = 0; i < targets.length; i++) {
			tempTargets[i][0] = targets[i][0] * 10 + 1;
			tempTargets[i][1] = targets[i][1] * 10 - 1;
		}
		
		// int[][] targets = {{4, 5}, {4, 8}, {10, 14}, {11, 13}, {5, 12}, {3, 7}, {1, 4}};
		// int[][] tempTargets = {{41, 49}, {41, 79}, {101, 139}, {111, 129}, {51, 119}, {31, 69}, {11, 39}};
		
		// 이차원 배열 tempTargets 정렬
		Arrays.sort(tempTargets, (o1, o2) -> {
			if (o1[1] == o2[1]) { // 뒤 원소가 같을 경우
				return o1[0] - o2[0]; // 앞 원소 기준 오름차순
			} else { // 뒤 원소가 같지 않을 경우
				return o1[1] - o2[1]; // 뒤 원소 기준 오름차순
			}
		});
		
		// int[][] tempTargets = {{11, 39}, {41, 49}, {31, 69}, {41, 79}, {51, 119}, {111, 129}, {101, 139}};
		
		int missilePoint = tempTargets[0][0] - 1; // 10 // 정렬 후 첫 번째 첫 원소보다 작은 값을 넣기 위해 -1 => 최초 무조건 아래 if문에 걸리게 됨
		
		for (int i = 0; i < tempTargets.length; i++) {
			
			if (missilePoint < tempTargets[i][0]) {
				missilePoint = tempTargets[i][1];
				System.out.println(missilePoint + "번 위치에 미사일 설치");
				answer++;
			}
		}
		
		return answer;
	}
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int[][] targets = {{4, 5}, {4, 8}, {10, 14}, {11, 13}, {5, 12}, {3, 7}, {1, 4}};
		
		System.out.println(solution(targets)); // 3
	}
}

프로그래머스 요격 시스템 문제 풀이 Java

public class Solution {
	
	// 네트워크
	
	static boolean[] visited = {};
	
	public static void dfs(int i, int[][] computers) {
		visited[i] = true;
		
		for(int j = 0; j < computers[i].length; j++) {
			
			if(!visited[j] && computers[i][j] == 1) {
				dfs(j, computers);
			}
		}
	}
	
	public static int solution(int n, int[][] computers) {
		int answer = 0;
		
		visited = new boolean[n];
		
		for(int i = 0; i < n; i++) {
        	
			if(!visited[i]) {
				answer++;
				dfs(i, computers);
			}
		}
        
		return answer;
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int n = 3; // 3대의 컴퓨터
		int[][] computers = {{1, 1, 0}, {1, 1, 0}, {0, 0, 1}}; // 연결된 네트워크
		
		System.out.println(solution(n, computers)); // 2
	}
}

프로그래머스 네트워크 문제 풀이 Java

public class Solution {
	
	// 단어 변환
	
	static boolean[] visited = {};
	static int gDepth = 0;
	
	public static boolean strCompare(String str1, String str2) { // str1과 str2의 길이가 같다는 조건 하에
		int strLength = str1.length();
		int cnt = 0;
		
		for(int i = 0; i < strLength; i++) {
			
			if(str1.charAt(i) != str2.charAt(i)) {
				cnt++;
			}
		}
		
		if(cnt == 1) { // 변형 조건에서 1글자만 바꿀 수 있는데 1글자만 다를 경우
			return true;
		} else {
			return false;
		}
	}
	
	public static int dfs(String begin, String target, String[] words, int depth) { // hit // cog // {"hot", "dot", "dog", "lot", "log", "cog"}
		
		int mDepth = 0;
		
		for(int i = 0; i < words.length; i++) {
			
			mDepth = depth;
			
			if(visited[i]) {
				continue;
			}
			
			if(strCompare(begin, words[i])) { // 1글자만 다른 경우, 즉 변경 가능한 경우
				begin = words[i]; // 바꿀 단어를 비교 대상으로 변경
				mDepth++;
				visited[i] = true; // 사용한 단어 방문 처리
				
				dfs(begin, target, words, mDepth);
				
				if(begin.equals(target)) {
					System.out.println(mDepth + "번 변경으로 가능");
					gDepth = mDepth;
					break;
				}
			} else {
				continue;
			}
		}
		return gDepth;
	}
	
	public static int solution(String begin, String target, String[] words) {
		int answer = 0;
		
		visited = new boolean[words.length];
		
		answer = dfs(begin, target, words, 0);
		
		return answer;
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String begin = "hit";
		String target = "cog";
		String[] words = {"hot", "dot", "dog", "lot", "log", "cog"}; // hot -> dot -> dog -> cog
		
		System.out.println(solution(begin, target, words)); // 4
	}
}

프로그래머스 단어 변환 문제 풀이 Java

import java.util.PriorityQueue;

public class Solution {
	
	// 디펜스 게임
	
	public static int solution(int n, int k, int[] enemy) {
		int answer = enemy.length; // 모든 라운드 클리어 가능할 경우의 리턴 값
		
		PriorityQueue<Integer> pq = new PriorityQueue<>(); // 무적권을 사용해 해치울 적의 수를 남기기 위한 우선순위 큐
		
		// 디펜스 게임 시작
		for(int i = 0; i < enemy.length; i++) { // 4, 2, 4, 5, 3, 3, 1
			pq.offer(enemy[i]); // 4 // 2, 4 // 2, 4, 4 // 2, 4, 4, 5 // 3, 4, 4, 5 // 3, 4, 4, 5
			
			// 무적권은 3개이므로 pq에 4개 이상 라운드가 담기면 그중 가장 적은 적이 나타나는 라운드는 병사를 소모하여 클리어
			if(pq.size() > k) { // false // false // false // true // true // true
				n -= pq.poll(); // 7 // 7 // 7 // 5 // 2 // -1
			}
			
			if(n < 0) { // false // false // false // false // false // true
				return i; // enemy 배열의 6번째 숫자에서 음수가 나오므로 enemy 배열의 5번째 숫자까지는 pass // 5라운드까지 진출 가능
			}
		}
		
		return answer; // 여기까지 내려왔다는 것은 모든 적을 해치우고도 병사가 남았다는 얘기 즉, 모든 라운드 클리어 가능
	}
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int n = 7; // 병사 수
		int k = 3; // 무적권 수
		int[] enemy = {4, 2, 4, 5, 3, 3, 1}; // 라운드별 적 수
		
		System.out.println(solution(n, k, enemy)); // 5
	}
}

프로그래머스 디펜스 게임 문제 풀이 Java

<MySQL>

SELECT A.AUTHOR_ID
     , B.AUTHOR_NAME
     , A.CATEGORY
     , SUM(A.PRICE * C.SALES) AS TOTAL_SALES
  FROM BOOK A
     , AUTHOR B
     , BOOK_SALES C
 WHERE A.AUTHOR_ID = B.AUTHOR_ID
   AND A.BOOK_ID = C.BOOK_ID
   AND DATE_FORMAT(C.SALES_DATE, '%Y-%m') = '2022-01'
 GROUP BY A.AUTHOR_ID, A.CATEGORY, B.AUTHOR_NAME
 ORDER BY A.AUTHOR_ID, A.CATEGORY DESC

<Oracle>

SELECT A.AUTHOR_ID
     , B.AUTHOR_NAME
     , A.CATEGORY
     , SUM(A.PRICE * C.SALES) AS TOTAL_SALES
  FROM BOOK A
     , AUTHOR B
     , BOOK_SALES C
 WHERE A.AUTHOR_ID = B.AUTHOR_ID
   AND A.BOOK_ID = C.BOOK_ID
   AND TO_CHAR(C.SALES_DATE, 'YYYY-MM') = '2022-01'
 GROUP BY A.AUTHOR_ID, A.CATEGORY, B.AUTHOR_NAME
 ORDER BY A.AUTHOR_ID, A.CATEGORY DESC

프로그래머스 저자 별 카테고리 별 매출액 집계하기 SQL

public class Solution {
	
	// 숫자 타자 대회
	
	public static int[][] weight = { // 가중치
			{1, 7, 6, 7, 5, 4, 5, 3, 2, 3}, // 0에서부터 0 ~ 9까지의 가중치
			{7, 1, 2, 4, 2, 3, 5, 4, 5, 6}, // 1에서부터 0 ~ 9까지의 가중치
			{6, 2, 1, 2, 3, 2, 3, 5, 4, 5}, // 2에서부터 0 ~ 9까지의 가중치
			{7, 4, 2, 1, 5, 3, 2, 6, 5, 4}, // 3에서부터 0 ~ 9까지의 가중치
			{5, 2, 3, 5, 1, 2, 4, 2, 3, 5}, // 4에서부터 0 ~ 9까지의 가중치
			{4, 3, 2, 3, 2, 1, 2, 3, 2, 3}, // 5에서부터 0 ~ 9까지의 가중치
			{5, 5, 3, 2, 4, 2, 1, 5, 3, 2}, // 6에서부터 0 ~ 9까지의 가중치
			{3, 4, 5, 6, 2, 3, 5, 1, 2, 4}, // 7에서부터 0 ~ 9까지의 가중치
			{2, 5, 4, 5, 3, 2, 3, 2, 1, 2}, // 8에서부터 0 ~ 9까지의 가중치
			{3, 6, 5, 4, 5, 3, 2, 4, 2, 1}  // 9에서부터 0 ~ 9까지의 가중치
	};
	public static int[][][] dp; // depth, 왼손 손가락 위치, 오른손 손가락 위치
	public static String targetNumbers; // numbers
	public static int targetDepth; // numbers의 depth
	
	public static int contest(int depth, int lPos, int rPos) {
		
		if (depth == targetDepth + 1) { // targetDepth를 넘었다면
			return 0;
		}
		
		if (dp[depth][lPos][rPos] != 0) { // 이미 구한 값이라면
			return dp[depth][lPos][rPos];
		}
		
		int targetPos = targetNumbers.charAt(depth) - '0'; // 1 // 7 // 5 // 6
		int result = Integer.MAX_VALUE;
		
		// 왼손 손가락으로 누르기
		if (targetPos != rPos) { // 오른손 손가락으로 바로 누를 수 있는 상황(오른손 손가락으로 눌렀을 때 최소 가중치가 보장되는 상황)이 아니라면, 왼손 손가락으로 눌러보기
			result = Math.min(contest(depth + 1, targetPos, rPos) + weight[lPos][targetPos], result);
		}
		
		// 오른손 손가락으로 누르기
		if (targetPos != lPos) { // 왼손 손가락으로 바로 누를 수 있는 상황(왼손 손가락으로 눌렀을 때 최소 가중치가 보장되는 상황)이 아니라면, 오른손 손가락으로 눌러보기
			result = Math.min(contest(depth + 1, lPos, targetPos) + weight[rPos][targetPos], result);
		}
		
		dp[depth][lPos][rPos] = result;
		
		return dp[depth][lPos][rPos];
	}
	
	public static int solution(String numbers) {
		targetNumbers = numbers; // "1756"
		targetDepth = numbers.length() - 1; // 3
		
		dp = new int [targetDepth + 1][10][10]; // 0 ~ 3 // 0 ~ 9 // 0 ~ 9
		
		return contest(0, 4, 6); // 초기 depth 0, 초기 왼손 손가락 위치 4, 초기 오른손 손가락 위치 6
	}
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String numbers = "1756"; // 0 ~ 3 depth
		
		System.out.println(solution(numbers)); // 10
	}
}

프로그래머스 숫자 타자 대회 문제 풀이 Java

<MySQL>

SELECT MST.YEAR
     , MST.MONTH
     , MST.GENDER
     , COUNT(MST.GENDER) AS USERS
  FROM (
         SELECT YEAR(A.SALES_DATE) AS YEAR
              , MONTH(A.SALES_DATE) AS MONTH
              , B.GENDER
           FROM ONLINE_SALE A
              , USER_INFO B
          WHERE A.USER_ID = B.USER_ID
            AND B.GENDER IN (0, 1)
       GROUP BY YEAR(A.SALES_DATE), MONTH(A.SALES_DATE), B.USER_ID
       ) MST
GROUP BY MST.YEAR, MST.MONTH, MST.GENDER
ORDER BY MST.YEAR, MST.MONTH, MST.GENDER

<Oracle>

SELECT MST.YEAR
     , MST.MONTH
     , MST.GENDER
     , COUNT(MST.GENDER) AS USERS
  FROM (
         SELECT EXTRACT(YEAR FROM A.SALES_DATE) AS YEAR
              , EXTRACT(MONTH FROM A.SALES_DATE) AS MONTH
              , B.GENDER
           FROM ONLINE_SALE A
              , USER_INFO B
          WHERE A.USER_ID = B.USER_ID
            AND B.GENDER IN (0, 1)
       GROUP BY EXTRACT(YEAR FROM A.SALES_DATE), EXTRACT(MONTH FROM A.SALES_DATE), B.USER_ID, B.GENDER
       ) MST
GROUP BY MST.YEAR, MST.MONTH, MST.GENDER
ORDER BY MST.YEAR, MST.MONTH, MST.GENDER

MySQL에서 MONTH(날짜), DATE_FORMAT(날짜, '%c') 차이

Oracle에서 EXTRACT(MONTH FROM 날짜), TO_CHAR(날짜, 'FMMM') 차이

정렬 기준의 차이를 확인할 수 있다.

프로그래머스 년, 월, 성별 별 상품 구매 회원 수 구하기 SQL

<MySQL>

SELECT A.PRODUCT_ID
     , B.PRODUCT_NAME
     , SUM(A.AMOUNT) * B.PRICE AS TOTAL_SALES
  FROM FOOD_ORDER A
     , FOOD_PRODUCT B
 WHERE A.PRODUCT_ID = B.PRODUCT_ID
   AND DATE_FORMAT(A.PRODUCE_DATE, '%Y-%m') = '2022-05'
 GROUP BY A.PRODUCT_ID
 ORDER BY SUM(A.AMOUNT) * B.PRICE DESC, A.PRODUCT_ID

<Oracle>

SELECT A.PRODUCT_ID
     , A.PRODUCT_NAME
     , A.PRICE * B.AMOUNT_SUM AS TOTAL_SALES
  FROM FOOD_PRODUCT A
     , (
         SELECT PRODUCT_ID, SUM(AMOUNT) AS AMOUNT_SUM
           FROM FOOD_ORDER
          WHERE TO_CHAR(PRODUCE_DATE, 'YYYY-MM') = '2022-05'
       GROUP BY PRODUCT_ID
       ) B
 WHERE A.PRODUCT_ID = B.PRODUCT_ID
 ORDER BY A.PRICE * B.AMOUNT_SUM DESC, A.PRODUCT_ID

프로그래머스 5월 식품들의 총매출 조회하기 SQL

+ Recent posts