‡ CODING TEST STUDY ‡

(미완) 삼성 코테 기출 (마법의 숲 탐색, 루돌프의 반란, 미로)

Trudy | 송연 2024. 11. 17. 14:44

삼성 코딩테스트 준비 방법

1. 코드트리
2. SW Expert Academy

 

먼저 코드트리에 기출들이 다 나와있으니 기출부터 여러 번 풀어보고, SW Expert Academy와 거의 동일하게 입출력이 주어지므로 여기에서 어떤 방식으로 시험이 이루어지는지 테스트 해보고 가는 게 좋다. 

 

삼성 코테는 빡구현의 문제들로 이루어져 있다보니 기출을 풀다보면 반복되는 유형들이 있어서 어떤 식으로 풀어야하는 지 감이 올 때가 있다. (회전, 사용자 클래스 등..)  근데 막상 시험장 가면 너무 코드가 길고 어려워서 내 코드에 내가 엉킴ㅠ 

 

또, 삼성은 코테를 푸는 시간도 채점 기준에 있기 때문에 문제를 미리 열어보지 않고, 최대한 빠르게 제출하고 미련 없이 건들지 않는게 더 좋다고 한다. 

 

https://www.codetree.ai/training-field/frequent-problems/problems/maze-tower-defense/description?page=1&pageSize=20&name=%EB%AF%B8%EB%A1%9C

 

코드트리 | 코딩테스트 준비를 위한 알고리즘 정석

국가대표가 만든 코딩 공부의 가이드북 코딩 왕초보부터 꿈의 직장 코테 합격까지, 국가대표가 엄선한 커리큘럼으로 준비해보세요.

www.codetree.ai

https://swexpertacademy.com/main/main.do

 

SW Expert Academy

SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!

swexpertacademy.com

 


마법의 숲 탐색 
| 삼성 SW 역량테스트 2024 상반기 오후 1번 문제

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class MagicForest {
	static int R, C;
	static int result;
	static int[][] map;
	static boolean[][] exit;
	static int[][] dxdy = new int[][] {{0, -1},{1, 0},{0, 1}, {-1, 0}};
	
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        R = Integer.parseInt(st.nextToken());
        C = Integer.parseInt(st.nextToken());
        int K = Integer.parseInt(st.nextToken());
        
        result = 0;
        map = new int[R][C];
        exit = new boolean[R][C];
        
        for (int i = 0; i < K; i++) {
        	st = new StringTokenizer(br.readLine());
        	int c = Integer.parseInt(st.nextToken());
            int d = Integer.parseInt(st.nextToken());
            
            moveDown(c,d,1);
		}
        
        System.out.print(result);
        return;
    }
    
//   Map: 1이면 골렘이 있는 곳, 2면 출구
    public static void moveDown(int c, int d, int depth) {
    	//1. 아래로 내려가기
    	if(check(c, depth)) {
    		saveMovement(c, depth, d);
    		
    		//출구 저장
    		exit[c + dxdy[d][0]][depth + dxdy[d][1]] = true;
    		map[c + dxdy[d][0]][depth + dxdy[d][1]] = 2;
    	} 
    	
    	//2. 안되면 서쪽으로 회전해서 내려가기
    	else if(check(c-1, depth+1)) {
    		saveMovement(c-1, depth+1, d);
    		
    		//출구 저장
    		exit[c + dxdy[d][0]][depth + dxdy[d][1] + 2] = true;
    		map[c + dxdy[d][0]][depth + dxdy[d][1] + 2] = 2;
    	}
    	
    	//3. 안되면 동쪽으로 회전해서 내려가기
    	else if(check(c+1, depth+1)) {
    		saveMovement(c+1, depth+1, d);
    		
    		//출구 저장
    		exit[c + dxdy[d][0] + 2][depth + dxdy[d][1]] = true;
    		map[c + dxdy[d][0] + 2][depth + dxdy[d][1]] = 2;
    	}
    	
    	//4. 셋 다 안되면 못 들어감
    	else {
    		// 4-1. 숲을 벗어나는 경우 => reset!
    		map = new int[R][C];
            exit = new boolean[R][C];
            return;
            
            //4-2. 벗어나지 않으면 제일 남부로 온 것. answer 저장!
    	}
    }
    
    public static boolean check(int c, int depth) {
    	if(map[c][depth]== 0 && map[c-1][depth]== 0 && map[c+1][depth]== 0
    			&& map[c][depth-1]== 0 && map[c][depth+1]== 0) {
    		return true;
    	}
    	return false;
    }
    
    public static void saveMovement(int a, int b, int d) {
    	//골렘 저장
		map[a][b] = 1;  map[a-1][b] = 1; map[a+1][b] = 1; 
		map[a][b-1] = 1; map[a][b-1] = 1; 
		
    }
}

 

 

미로 찾기

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.StringTokenizer;

public class Maze {
    static int N, M, K;
    static int eX, eY; // 출구 정보
    static int[][] map; // 미로
    static List<Pair> people; // 참가자 위치
    static int moveSum = 0; // 총 이동 거리

    static class Pair implements Comparable<Pair> {
        int x, y; // 참가자 좌표

        public Pair(int x, int y) {
            this.x = x;
            this.y = y;
        }

        @Override
        public int compareTo(Pair o) {
            if (this.x - o.x == 0) {
                return this.y - o.y;
            }
            return this.x - o.x;
        }

        @Override
        public String toString() {
            return "Pair [x=" + x + ", y=" + y + "]";
        }
    }

    public static boolean isBound(int x, int y) {
        return x > 0 && x <= N && y > 0 && y <= N;
    }

    // 모든 사람들을 이동
    public static void movePeople() {
        List<Pair> exited = new ArrayList<>();

        for (Pair p : people) {
            // 상하로 움직일 수 있으면 움직이기
            // 상
            if (eX - p.x < 0 && isBound(p.x - 1, p.y)) {
                if (map[p.x - 1][p.y] == 0) {
                    p.x--;
                    moveSum++;
                }
            }
            // 하
            else if (eX - p.x > 0 && isBound(p.x + 1, p.y)) {
                if (map[p.x + 1][p.y] == 0) {
                    p.x++;
                    moveSum++;
                }
            }
            // 좌우로 움직일 수 있으면 움직이기
            // 좌
            else if (eY - p.y < 0 && isBound(p.x, p.y - 1)) {
                if (map[p.x][p.y - 1] == 0) {
                    p.y--;
                    moveSum++;
                }
            }
            // 우
            else if (eY - p.y > 0 && isBound(p.x, p.y + 1)) {
                if (map[p.x][p.y + 1] == 0) {
                    p.y++;
                    moveSum++;
                }
            }

            // 탈출 확인
            if (p.x == eX && p.y == eY) {
                exited.add(p);
            }
        }

        // 탈출한 사람 제거
        people.removeAll(exited);
    }

    // 미로 회전
    public static void makeSqr() {
        // 가장 가까운 참가자 찾기
        Pair p = findNear();

        // 참가자가 없으면 회전하지 않음
        if (p == null) {
            return;
        }

        // 정사각형 만들기
        int minR = Math.min(p.x, eX);
        int maxR = Math.max(p.x, eX);
        int minC = Math.min(p.y, eY);
        int maxC = Math.max(p.y, eY);

        // 가로와 세로 중 큰 값을 선택하여 정사각형 변 길이 결정
        int sideLength = Math.max(maxR - minR, maxC - minC);

        // 좌상단 좌표 보정 (경계 체크 추가)
        int resultR = Math.max(1, minR);
        int resultC = Math.max(1, minC);

        if (resultR + sideLength > N) {
            resultR = N - sideLength;
        }

        if (resultC + sideLength > N) {
            resultC = N - sideLength;
        }

        // 회전
        spinMaze(resultR, resultC, sideLength + 1);
    }

    // 시계 방향으로 90도 회전
    public static void spinMaze(int sx, int sy, int n) {
        // 미로 90도 회전
        int[][] tmpMap = new int[N + 1][N + 1];

        for (int x = sx; x < sx + n; x++) {
            for (int y = sy; y < sy + n; y++) {
                // (0, 0)으로 이동
                int nx = x - sx;
                int ny = y - sy;

                // 회전 (x, y) -> (y, n - x - 1)
                int tmp = nx;
                nx = ny;
                ny = n - tmp - 1;

                // 원래 위치로 이동
                nx += sx;
                ny += sy;
                tmpMap[nx][ny] = map[x][y];
            }
        }

        // 회전한 값을 실제 map에 반영
        for (int x = sx; x < sx + n; x++) {
            for (int y = sy; y < sy + n; y++) {
                map[x][y] = tmpMap[x][y];
            }
        }

        // 참가자 회전
        for (Pair p : people) {
            if (p.x >= sx && p.x < sx + n && p.y >= sy && p.y < sy + n) {
                int ox = p.x - sx;
                int oy = p.y - sy;

                int rx = oy;
                int ry = n - ox - 1;

                p.x = rx + sx;
                p.y = ry + sy;
            }
        }

        // 출구 회전
        int ox = eX - sx;
        int oy = eY - sy;

        int rx = oy;
        int ry = n - ox - 1;

        eX = rx + sx;
        eY = ry + sy;

        // 벽 내구도 감소 (0 이하로 떨어지지 않도록 조정)
        for (int x = sx; x < sx + n; x++) {
            for (int y = sy; y < sy + n; y++) {
                if (map[x][y] > 0) {
                    map[x][y] = Math.max(0, map[x][y] - 1); // 내구도 0 이하 방지
                }
            }
        }
    }

    // 가장 가까운 사람 찾기
    public static Pair findNear() {
        if (people.isEmpty()) {
            return null;
        }

        int minDist = Integer.MAX_VALUE;
        Pair minPair = null;

        Collections.sort(people);

        for (Pair p : people) {
            int dist = Math.abs(p.x - eX) + Math.abs(p.y - eY);
            if (minDist > dist) {
                minDist = dist;
                minPair = p;
            }
        }

        return minPair;
    }

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        K = Integer.parseInt(st.nextToken());

        map = new int[N + 1][N + 1];
        for (int i = 1; i <= N; i++) {
            st = new StringTokenizer(br.readLine());
            for (int j = 1; j <= N; j++) {
                map[i][j] = Integer.parseInt(st.nextToken());
            }
        }

        people = new ArrayList<>();
        for (int i = 0; i < M; i++) {
            st = new StringTokenizer(br.readLine());
            int x = Integer.parseInt(st.nextToken());
            int y = Integer.parseInt(st.nextToken());
            people.add(new Pair(x, y));
        }

        // 출구 위치 저장
        st = new StringTokenizer(br.readLine());
        eX = Integer.parseInt(st.nextToken());
        eY = Integer.parseInt(st.nextToken());

        while (K-- > 0) {
            // 모두 탈출했으면 끝
            if (people.size() == 0) break;

            // 모든 참가자가 한 칸씩 이동
            movePeople();

            // 미로 회전
            makeSqr();
        }

        // 모든 참가자들의 이동 거리 합 출력
        System.out.println(moveSum);
        // 출구 좌표 출력
        System.out.println(eX + " " + eY);
    }
}

 

루돌프의 반란

| 삼성 SW 역량테스트 2023 하반기 오후 1번 문제

 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.StringTokenizer;

public class Maze {
    static int N, M, K;
    static int eX, eY; // 출구 정보
    static int[][] map; // 미로
    static List<Pair> people; // 참가자 위치
    static int moveSum = 0; // 총 이동 거리

    static class Pair implements Comparable<Pair> {
        int x, y; // 참가자 좌표

        public Pair(int x, int y) {
            this.x = x;
            this.y = y;
        }

        @Override
        public int compareTo(Pair o) {
            if (this.x - o.x == 0) {
                return this.y - o.y;
            }
            return this.x - o.x;
        }

        @Override
        public String toString() {
            return "Pair [x=" + x + ", y=" + y + "]";
        }
    }

    public static boolean isBound(int x, int y) {
        return x > 0 && x <= N && y > 0 && y <= N;
    }

    // 모든 사람들을 이동
    public static void movePeople() {
        List<Pair> exited = new ArrayList<>();

        for (Pair p : people) {
            // 상하로 움직일 수 있으면 움직이기
            // 상
            if (eX - p.x < 0 && isBound(p.x - 1, p.y)) {
                if (map[p.x - 1][p.y] == 0) {
                    p.x--;
                    moveSum++;
                }
            }
            // 하
            else if (eX - p.x > 0 && isBound(p.x + 1, p.y)) {
                if (map[p.x + 1][p.y] == 0) {
                    p.x++;
                    moveSum++;
                }
            }
            // 좌우로 움직일 수 있으면 움직이기
            // 좌
            else if (eY - p.y < 0 && isBound(p.x, p.y - 1)) {
                if (map[p.x][p.y - 1] == 0) {
                    p.y--;
                    moveSum++;
                }
            }
            // 우
            else if (eY - p.y > 0 && isBound(p.x, p.y + 1)) {
                if (map[p.x][p.y + 1] == 0) {
                    p.y++;
                    moveSum++;
                }
            }

            // 탈출 확인
            if (p.x == eX && p.y == eY) {
                exited.add(p);
            }
        }

        // 탈출한 사람 제거
        people.removeAll(exited);
    }

    // 미로 회전
    public static void makeSqr() {
        // 가장 가까운 참가자 찾기
        Pair p = findNear();

        // 참가자가 없으면 회전하지 않음
        if (p == null) {
            return;
        }

        // 정사각형 만들기
        int minR = Math.min(p.x, eX);
        int maxR = Math.max(p.x, eX);
        int minC = Math.min(p.y, eY);
        int maxC = Math.max(p.y, eY);

        // 가로와 세로 중 큰 값을 선택하여 정사각형 변 길이 결정
        int sideLength = Math.max(maxR - minR, maxC - minC);

        // 좌상단 좌표 보정 (경계 체크 추가)
        int resultR = Math.max(1, minR);
        int resultC = Math.max(1, minC);

        if (resultR + sideLength > N) {
            resultR = N - sideLength;
        }

        if (resultC + sideLength > N) {
            resultC = N - sideLength;
        }

        // 회전
        spinMaze(resultR, resultC, sideLength + 1);
    }

    // 시계 방향으로 90도 회전
    public static void spinMaze(int sx, int sy, int n) {
        // 미로 90도 회전
        int[][] tmpMap = new int[N + 1][N + 1];

        for (int x = sx; x < sx + n; x++) {
            for (int y = sy; y < sy + n; y++) {
                // (0, 0)으로 이동
                int nx = x - sx;
                int ny = y - sy;

                // 회전 (x, y) -> (y, n - x - 1)
                int tmp = nx;
                nx = ny;
                ny = n - tmp - 1;

                // 원래 위치로 이동
                nx += sx;
                ny += sy;
                tmpMap[nx][ny] = map[x][y];
            }
        }

        // 회전한 값을 실제 map에 반영
        for (int x = sx; x < sx + n; x++) {
            for (int y = sy; y < sy + n; y++) {
                map[x][y] = tmpMap[x][y];
            }
        }

        // 참가자 회전
        for (Pair p : people) {
            if (p.x >= sx && p.x < sx + n && p.y >= sy && p.y < sy + n) {
                int ox = p.x - sx;
                int oy = p.y - sy;

                int rx = oy;
                int ry = n - ox - 1;

                p.x = rx + sx;
                p.y = ry + sy;
            }
        }

        // 출구 회전
        int ox = eX - sx;
        int oy = eY - sy;

        int rx = oy;
        int ry = n - ox - 1;

        eX = rx + sx;
        eY = ry + sy;

        // 벽 내구도 감소 (0 이하로 떨어지지 않도록 조정)
        for (int x = sx; x < sx + n; x++) {
            for (int y = sy; y < sy + n; y++) {
                if (map[x][y] > 0) {
                    map[x][y] = Math.max(0, map[x][y] - 1); // 내구도 0 이하 방지
                }
            }
        }
    }

    // 가장 가까운 사람 찾기
    public static Pair findNear() {
        if (people.isEmpty()) {
            return null;
        }

        int minDist = Integer.MAX_VALUE;
        Pair minPair = null;

        Collections.sort(people);

        for (Pair p : people) {
            int dist = Math.abs(p.x - eX) + Math.abs(p.y - eY);
            if (minDist > dist) {
                minDist = dist;
                minPair = p;
            }
        }

        return minPair;
    }

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        K = Integer.parseInt(st.nextToken());

        map = new int[N + 1][N + 1];
        for (int i = 1; i <= N; i++) {
            st = new StringTokenizer(br.readLine());
            for (int j = 1; j <= N; j++) {
                map[i][j] = Integer.parseInt(st.nextToken());
            }
        }

        people = new ArrayList<>();
        for (int i = 0; i < M; i++) {
            st = new StringTokenizer(br.readLine());
            int x = Integer.parseInt(st.nextToken());
            int y = Integer.parseInt(st.nextToken());
            people.add(new Pair(x, y));
        }

        // 출구 위치 저장
        st = new StringTokenizer(br.readLine());
        eX = Integer.parseInt(st.nextToken());
        eY = Integer.parseInt(st.nextToken());

        while (K-- > 0) {
            // 모두 탈출했으면 끝
            if (people.size() == 0) break;

            // 모든 참가자가 한 칸씩 이동
            movePeople();

            // 미로 회전
            makeSqr();
        }

        // 모든 참가자들의 이동 거리 합 출력
        System.out.println(moveSum);
        // 출구 좌표 출력
        System.out.println(eX + " " + eY);
    }
}

 

 

 

;__;