상세 컨텐츠

본문 제목

[1일1커밋 3D] LeetCode SQL & 백준 JAVA 23971, 5073, 2292, 7562 (수학.. 그래프 순회)

취준/2. 코딩테스트

by ranlan 2024. 9. 4. 20:41

본문

728x90

리트코드 알려준 후배님께 감사함을 느끼며 늘 그렇듯 SQL로 몸풀기부터! 

 

LeetCode SQL 50

Basic Aggregate Functions | 1251. Average Selling Price

쉬운 줄 알고 풀었는데 요상하게 생각보다 오래 걸린 문제.. 처음에는 서브쿼리 쓰고 난리였는데 풀다보니 감이 잡혔다.

첫번째 통과 못한 코드 (아래 틀린 문제 있음)

SELECT P.PRODUCT_ID, IFNULL(ROUND(SUM(PRICE*UNITS)/SUM(UNITS), 2), 0) AS AVERAGE_PRICE
FROM PRICES P
LEFT JOIN UNITSSOLD U
ON P.PRODUCT_ID = U.PRODUCT_ID
WHERE PURCHASE_DAT BETWEEN START_DATE AND END_DATE
GROUP BY PRODUCT_ID;

사실 저 날짜 조건을 어떻게 거나 고민이었는데 ㅋㅋ 생각보다 어렵지 않았다.. 나 SQL은 자신있었는데 이렇게 글로 써진 문제로 만나니까 당황스럽다.

답안 코드

SELECT P.PRODUCT_ID, IFNULL(ROUND(SUM(PRICE*UNITS)/SUM(UNITS), 2), 0) AS AVERAGE_PRICE
FROM PRICES P
LEFT JOIN UNITSSOLD U
ON P.PRODUCT_ID = U.PRODUCT_ID
AND PURCHASE_DATE BETWEEN START_DATE AND END_DATE
GROUP BY PRODUCT_ID;

처음 코드가 도저히 왜 틀렸는지 몰라서 다른 사람들이 푼거 살짝 보고 풀었다.

 

📚 JOIN절에서 ON과 WHERE 조건의 차이

  • JOIN 전에 조건 필터링
  • JOIN 후에 조건 필터링
  • INNER JOIN시 차이 없으나, OUTER JOIN 시 원하고자 하는 결과를 얻기 위해선 ON 절에 조건을 거는 것도 생각

문제의 경우, 날짜 필터링 후 PRODUCT_ID = 3인 상품에 대해 판매된 데이터가 없더라도 없어지지 않고 NULL로 값이 있어야한다. WHERE 조건 사용하게 되면 NULL이 아니라 결과 행에서 아예 사라지게 된다. 그럼 나의 틀린 답안처럼 결과에 0으로 표시할 수 없다.

 

Select | 1148. Article Views I

SELECT DISTINCT AUTHOR_ID AS ID
FROM VIEWS
WHERE AUTHOR_ID = VIEWER_ID
ORDER BY ID ;

 

Basic Joins | 1068. Product Sales Analysis I

SELECT PRODUCT_NAME, YEAR, PRICE
FROM SALES S
JOIN PRODUCT P
ON S.PRODUCT_ID = P.PRODUCT_ID;

 


 

BaekJoon 백준 

1일 1알고리즘 문제집으로는 [IT기업 및 대기업 계열사 코테보면서 비슷했던 문제들(지속적으로 업데이트 중)] 

 

23971. ZOAC 4 https://www.acmicpc.net/problem/23971

브론즈3 | 수학
import java.util.Scanner;

public class Main {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		
		float h = sc.nextFloat();
		float w = sc.nextFloat();
		float n = sc.nextFloat();
		float m = sc.nextFloat();
		
		n += 1; // 사람 포함 실제로 차지하는 칸의 수 
		m += 1;
		
        int ans = (int)(Math.ceil(h/n)*Math.ceil(w/m));
		System.out.println(ans);  
	}
}

큰 사각형(강의실) 안에 작은 사각형(사람~사람이 차지하는 공간)이 몇개 들어가는지 세는 문제

 

5073. 삼각형과 세 변 https://www.acmicpc.net/problem/5073

브론즈3 |  구현
import java.util.Scanner;

public class Main {
	
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		
		while(true) {
			int a = sc.nextInt();
			int b = sc.nextInt();
			int c = sc.nextInt();
			
			if(a==0 && b==0 && c==0) break;
			int sum = a+b+c;
			int max = Math.max(a, Math.max(b, c));
			if(max >= sum-max) System.out.println("Invalid");
			else {
				if(a==b && b==c) System.out.println("Equilateral");
				else if(a==b || b==c || a==c) System.out.println("Isosceles");
				else System.out.println("Scalene");
			}
		}

	}

}

 

2292. 벌집 https://www.acmicpc.net/problem/2292

브론즈2 | 수학
import java.util.Scanner;

public class Main {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		
		int n = sc.nextInt();
		
		int i = 1;
		int move = 1;
		while(true) {
			if(n<=move) break;
			move = move+((i+1)*6-6);
			i++;
		}
		System.out.println(i);
		
	}
}

 

너무 수학 문제만 푼거같아서 알고리즘 문제도 풀러 이제 총총,,

 

7562. 나이트의 이동 https://www.acmicpc.net/problem/7562

실버1 | 그래프 순회 | BFS
import java.util.*;

public class Main {
	
	static int t, n;
	static class Point{
		int x;
		int y;
		public Point() {}
		public Point(int x, int y) {
			this.x = x;
			this.y = y;
		}
	}
	static int[][] moved = {{1, 2}, {2, 1}, {1, -2}, {2, -1}, {-1, -2}, {-2, -1}, {-1, 2}, {-2, 1}};

	static boolean visited[][];
	static Point start, end;
	static int count;
	
	static int[][] arr;	
	
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		
		t = sc.nextInt();
		
		for(int tc=0; tc<t; tc++) {
			n = sc.nextInt(); // 한 판의 길이
			
			visited = new boolean[n][n];
			arr = new int[n][n];
			start = new Point();
			end = new Point();
			count = 0;
			 
			
			start.x = sc.nextInt();
			start.y = sc.nextInt();
			end.x = sc.nextInt();
			end.y = sc.nextInt();
			
			bfs(start);
			
			System.out.println(arr[end.x][end.y]);
		}
		
	}
	
	static void bfs(Point start) {
		visited[start.x][start.y]=true;
		
		Queue<Point> queue = new LinkedList<Point>();
		queue.add(start);
		
		while(!queue.isEmpty()) {
			Point now = queue.poll();
			
			for(int i=0; i<8; i++) {
				int mx = moved[i][0] + now.x;
				int my = moved[i][1] + now.y;
				if(isIn(new Point(mx, my)) && !visited[mx][my]) {
					queue.add(new Point(mx, my));
					visited[mx][my]=true;
					arr[mx][my] = arr[now.x][now.y]+1;
				}
			}
		}
	}
	
	static boolean isIn(Point m) {
		if(m.x >= n || m.x < 0 || m.y >= n || m.y <0) return false;
		else return true;
	
	}
}

 

그래프 순회 문제 푼지 너무 오래된거같아서 코드 까먹기 전에 다시 복습

최단 거리 구하는 문제의 경우 BFS를 활용한다! 는 기억해서 BFS로 시작했는데.. 배열에 카운팅한 숫자 저장하면서 최단 거리 구하는 방법은 고새 까먹은듯 하다. 

처음에 아래처럼 이동거리만큼 카운팅하고 최종 목적지에 도달하면 리턴하려 했다. (바보같은 방법)

import java.util.*;

public class Main {
	
	static int t, n;
	static class Point{
		int x;
		int y;
		public Point() {}
		public Point(int x, int y) {
			this.x = x;
			this.y = y;
		}
	}
	static int[][] moved = {{1, 2}, {2, 1}, {1, -2}, {2, -1}, {-1, -2}, {-2, -1}, {-1, 2}, {-2, 1}};

	static boolean visited[][];
	static Point start, end;
	static int count;
	
	
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		
		t = sc.nextInt();
		
		for(int tc=0; tc<t; tc++) {
			n = sc.nextInt(); // 한 판의 길이
			
			visited = new boolean[n][n];
			start = new Point();
			end = new Point();
			count = 0;
			 
			
			start.x = sc.nextInt();
			start.y = sc.nextInt();
			end.x = sc.nextInt();
			end.y = sc.nextInt();
			
//			bfs(start);
			
			System.out.println(bfs(start));
		}
		
	}
	
	static int bfs(Point start) {
		visited[start.x][start.y]=true;
		
		Queue<Point> queue = new LinkedList<Point>();
		queue.add(start);
		
		while(!queue.isEmpty()) {
			Point now = queue.poll();
			System.out.printf("%d %d\n", now.x, now.y);
			if(now.x==end.x && now.y==end.y) break;
			
			for(int i=0; i<8; i++) {
				int mx = moved[i][0] + now.x;
				int my = moved[i][1] + now.y;
				if(mx >= n || mx < 0 || my >= n || my <0) break;
				if(mx == end.x && my == end.y) {
					return count;
				}
				if(!visited[mx][my]) {
					queue.add(new Point(mx, my));
					visited[mx][my]=true;
					count++;
				}
			}
		}
		
		return count;
	}
}

감도 안와서 다른 풀이 살짝 보다가 방법을 찾고 결국 해결!!

 

⭐️ 비슷한 유형의 문제 : 2178. 숨바꼭질 https://www.acmicpc.net/problem/2178 (https://juran-devblog.tistory.com/272)

 

728x90

관련글 더보기

댓글 영역