본문 바로가기

알고리즘/코드트리

놀이기구 탑승[G5]

목차

     

    현재 삼성 코딩테스트와는 다른 유형의 문제라고 생각이 들었다.

    상당히 쉬운 편. 별다른 어려움 없이 풀었다.

     

    https://www.codetree.ai/training-field/frequent-problems/problems/go-on-the-rides/description?page=1&pageSize=20

     

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

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

    www.codetree.ai

     

    //쉽다. 난이도 제일 낮을듯. 구현만 제대로 하면 됨
    // 1시간 30분
    
    import java.util.*;
    import java.io.*;
    
    public class Main {
    	static int N, fRes;
    	static int[][] map;
    	static ArrayList<Person> persons = new ArrayList<>();
    	// L U R D
    	static final int[] dr = {0, -1, 0, 1};
    	static final int[] dc = {-1, 0, 1, 0};
    	static int[] score = {0, 1, 10, 100, 1000};
    	
    	public static void main(String[] args) throws Exception {
    		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    		StringTokenizer st = new StringTokenizer(br.readLine());
    		N = Integer.parseInt(st.nextToken());
    		map = new int[N][N];
    		
    		for(int i = 0; i < N * N; i++) {
    			st = new StringTokenizer(br.readLine());
    			persons.add(new Person(
    					Integer.parseInt(st.nextToken()),
    					Integer.parseInt(st.nextToken()),
    					Integer.parseInt(st.nextToken()),
    					Integer.parseInt(st.nextToken()),
    					Integer.parseInt(st.nextToken())
    			));
    		}
    		
    		
    		//N번까지의 사람 재귀
    		int num = persons.size();
    		for(int i = 0; i < num; i++) {
    			solve(i);
    		}
    		
    		System.out.println(fRes);
    	}
    
    	static void solve(int now) {
    		int n1 = persons.get(now).n1;
    		int n2 = persons.get(now).n2;
    		int n3 = persons.get(now).n3;
    		int n4 = persons.get(now).n4;
    		//최적 위치 선정
    		actionOne(n1, n2, n3, n4, now); 
    		
    		//점수 계산
    		fRes = getScore();
    	}
    	
    	static int getScore() {
    		int res = 0;
    		for(int i = 0; i < N; i++) {
    			for(int j = 0; j < N; j++) {
    				res += getNowPosScore(i, j); //좋아하는 친구 점수 합산
    			}
    		}
    		return res;
    	}
    	
    	static int getNowPosScore(int r, int c) {
    		for(int i = 0; i < persons.size(); i++) {
    			if(persons.get(i).checkMe(map[r][c])) { //해당 포지션의 친구 리스트 찾기
    				int[]friArr = persons.get(i).getMyFriends(); //친구 리스트
    				int scoreCount = 0; //결과
    				
    				//4방탐색하기
    				for(int k = 0; k < 4; k++) {
    					int nr = r + dr[k];
    					int nc = c + dc[k];
    					if(cantGo(nr, nc)) continue; //맵 밖으로 벗어나면 스킵
    					for(int l = 0; l < friArr.length; l++) {
    						if(map[nr][nc] == friArr[l]) {
    							scoreCount++;
    						}
    					}
    				}
    				
    				return score[scoreCount];
    			}
    		}
    		
    		return 0;
    	}
    	
    	static void actionOne(int n1, int n2, int n3, int n4, int now) {
    		int maxFriend = 0; //최대 친구 있는 숫자
    		int maxR = 999, maxC = 999; //그 좌표
    		int maxEmpty = -1; //공백
    		
    		
    		for(int i = 0; i < N; i++) {
    			SOLVE:
    			for(int j = 0; j < N; j++) {
    				if(map[i][j] != 0) continue; //사람 있는 자리 스킵
    				//4방 친구 체크
    				int nowFriend = 0;
    				int nowEmpty = 0;
    				for(int k = 0; k < 4; k++) {
    					int r = i + dr[k];
    					int c = j + dc[k];
    					if(cantGo(r, c)) continue; //맵 밖으로 벗어나면 스킵
    					if(actionOneCheckMyFriend(n1, n2, n3, n4, r, c)) {
    						nowFriend++;
    						continue; //스킵
    					}
    					if(actionOneCheckEmpty(r, c)) nowEmpty++; //공백이라면 추가
    				}
    				
    				//1번 만약 현재 좌표가 최고라면 갱신
    				if(nowFriend > maxFriend) {
    					maxFriend = nowFriend;
    					maxR = i; maxC = j;
    					maxEmpty = nowEmpty;
    					continue SOLVE;
    				}
    				
    				//동등하다면 2번 조건
    				if(nowFriend == maxFriend) {
    					if(nowEmpty > maxEmpty) { //비어있는 칸이 제일 많다면
    						maxFriend = nowFriend;
    						maxR = i; maxC = j;
    						maxEmpty = nowEmpty;
    						continue SOLVE;
    					}
    					//3번 조건
    					if(nowEmpty == maxEmpty) {
    						if(i < maxR) {
    							maxFriend = nowFriend;
    							maxR = i; maxC = j;
    							maxEmpty = nowEmpty;
    							continue SOLVE;
    						}
    						//4번 조건
    						if(i == maxR) {
    							if(j < maxC) {
    								maxFriend = nowFriend;
    								maxR = i; maxC = j;
    								maxEmpty = nowEmpty;
    							}
    						}
    					}
    				}
    			}
    		}
    		
    		//값 저장
    		map[maxR][maxC] = persons.get(now).me;
    	}
    	
    	static boolean actionOneCheckEmpty(int r, int c) {
    		if(map[r][c] == 0) return true;
    		return false;
    	}
    	
    	static boolean actionOneCheckMyFriend(int n1, int n2, int n3, int n4, int r, int c) {
    		if(map[r][c] == n1 || map[r][c] == n2 || map[r][c] == n3 || map[r][c] == n4) return true;
    		return false;
    	}
    	
    	static boolean cantGo(int r, int c) {
    		if(r < 0 || c < 0 || r >= N || c >= N) return true;
    		return false;
    	}
    	
    }
    
    class Person {
    	int me;
    	int n1, n2, n3, n4;
    	Person(int me, int n1, int n2, int n3, int n4) {
    		this.me = me;
    		this.n1 = n1;
    		this.n2 = n2;
    		this.n3 = n3;
    		this.n4 = n4;
    	}
    	
    	boolean checkMe(int val) {
    		if(me == val) return true;
    		return false;
    	}
    	
    	int[] getMyFriends() {
    		return new int[] {n1, n2, n3, n4};
    	}
    }

    '알고리즘 > 코드트리' 카테고리의 다른 글

    나무박멸[G4]  (0) 2024.04.07
    원자 충돌[G4]  (0) 2023.11.02
    팩맨[G1]  (1) 2023.11.02
    예술성[G3]  (0) 2023.11.02
    나무박멸[G4] (틀림 - 널포인터 이슈가 있는 듯)  (0) 2023.11.02