삼성 코딩테스트 준비 방법
1. 코드트리
2. SW Expert Academy
먼저 코드트리에 기출들이 다 나와있으니 기출부터 여러 번 풀어보고, SW Expert Academy와 거의 동일하게 입출력이 주어지므로 여기에서 어떤 방식으로 시험이 이루어지는지 테스트 해보고 가는 게 좋다.
삼성 코테는 빡구현의 문제들로 이루어져 있다보니 기출을 풀다보면 반복되는 유형들이 있어서 어떤 식으로 풀어야하는 지 감이 올 때가 있다. (회전, 사용자 클래스 등..) 근데 막상 시험장 가면 너무 코드가 길고 어려워서 내 코드에 내가 엉킴ㅠ
또, 삼성은 코테를 푸는 시간도 채점 기준에 있기 때문에 문제를 미리 열어보지 않고, 최대한 빠르게 제출하고 미련 없이 건들지 않는게 더 좋다고 한다.
코드트리 | 코딩테스트 준비를 위한 알고리즘 정석
국가대표가 만든 코딩 공부의 가이드북 코딩 왕초보부터 꿈의 직장 코테 합격까지, 국가대표가 엄선한 커리큘럼으로 준비해보세요.
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);
}
}
'‡ CODING TEST STUDY ‡' 카테고리의 다른 글
[JAVA] SWEA | 2382. [모의 SW 역량테스트] 미생물 격리 (0) | 2024.11.17 |
---|---|
[JAVA] SWEA | 1213. [S/W 문제해결 기본] 3일차 - String (0) | 2024.11.16 |
[JAVA] SWEA | 1204. [S/W 문제해결 기본] 1일차 - 최빈수 구하기 (0) | 2024.11.16 |
[Java] 소수 판별 - 에라토스테네스의 채 (0) | 2024.05.18 |