[Algorithm/Java] 백준 20006번 - 랭킹전 대기열 (작성중)
https://www.acmicpc.net/problem/20006
🔍 문제 풀이
문제 도식화
List<List<User>> rooms
rooms.get(0)→ 첫 번째 방
rooms.get(1) → 두 번째 방
rooms.get(2) → 세 번째 방 …
이렇게 방에 접근할 수 있.
그리고 그 방의 처음 들어간 사람은 항상 get(0)이 된다.
즉, 두 번째 방에 처음 들어간 사람은
User firstInSecondRoom = rooms.get(1).get(0);
System.out.println(firstInSecondRoom.level + " " + firstInSecondRoom.name);
이렇게 꺼내면 된다.
정리
rooms.get(방인덱스) → 해당 방 전체 리스트
rooms.get(방인덱스).get(0) → 그 방의 첫 번째(=기준) 유저
// 첫 번째 방 기준 레벨
int base1 = rooms.get(0).get(0).level;
// 두 번째 방 기준 레벨
int base2 = rooms.get(1).get(0).level;
💻 코드
[방법 1] 일중리스트
import java.io.*;
import java.util.*;
public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        // input
        StringTokenizer st = new StringTokenizer(br.readLine());
        StringBuilder sb = new StringBuilder();
        int p = Integer.parseInt(st.nextToken()); // 플레이어 수
        int m = Integer.parseInt(st.nextToken()); // 방의 정원
        Player[] players = new Player[p];
        // 정보 저장
        for (int i = 0; i < p; i++) {
            st = new StringTokenizer(br.readLine());
            int level = Integer.parseInt(st.nextToken()); // 레벨
            String name = st.nextToken(); // 닉네임
            players[i] = new Player(level, name);
        }
        for (int i = 0; i < p; i++) {
            ArrayList<Player> room = new ArrayList<>();
            if (!players[i].check) {
                for (int j = i; j < p; j++) {
                    if (room.size() == m) break;
                    int level = players[j].level;
                    String name = players[j].name;
                    if (!players[j].check && players[i].level - 10 <= level && level <= players[i].level + 10 ) {
                        players[j].check = true;
                        room.add(new Player(level, name));
                    }
                }
                Collections.sort(room, (a,b) -> a.name.compareTo(b.name));
                if (room.size() == m) sb.append("Started!").append("\n");
                else sb.append("Waiting!").append("\n");
                for (Player player : room) {
                    sb.append(player.level).append(" ").append(player.name).append("\n");
                }
            }
        }
        System.out.println(sb);
    }
    static class Player {
        int level;
        String name;
        boolean check;
        public Player(int level, String name) {
            this.level = level;
            this.name = name;
        }
    }
}
[방법 2] 이중 리스트
rooms가 처음엔 비어 있으니까, 첫 번째 유저를 처리할 때는 안쪽 for(List<User> room : rooms)가 아예 실행되지 않음
따라서 첫 번쨰 유저부터 방 생성
import java.io.*;
import java.util.*;
public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        // input
        StringTokenizer st = new StringTokenizer(br.readLine());
        int p = Integer.parseInt(st.nextToken()); // 플레이어 수
        int m = Integer.parseInt(st.nextToken()); // 방의 정원
        // 정보 저장
        List<User> users = new ArrayList<>();
        for (int i = 0; i < p; i++) {
            st = new StringTokenizer(br.readLine());
            int level = Integer.parseInt(st.nextToken()); // 레벨
            String name = st.nextToken(); // 닉네임
            users.add(new User(level, name));
        }
        // 방들을 리스트로 관리 (리스트 안에 리스트)
        List<List<User>> rooms = new ArrayList<>(); // 방 하나씩 순회
        for(User user:users){
            boolean joined = false;
            for(List<User> room : rooms) {
                if(room.size() < m) {
                    int baseLevel = room.get(0).level; // 그 방 안에서 0번쨰로 들어온 유저
                    if(baseLevel - 10 <= user.level && user.level <= baseLevel + 10){
                        room.add(user);
                        joined = true;
                        break;
                    }
                }
            }
            if(!joined) {
                List<User> newRoom = new ArrayList<>();
                newRoom.add(user);
                rooms.add(newRoom);
            }
        }
        // 출력
        StringBuilder sb = new StringBuilder();
        for(List<User> room : rooms) {
            if(room.size() == m) sb.append("Started!\n");
            else sb.append("Waiting!\n");
            Collections.sort(room, (a, b) -> a.name.compareTo(b.name));
            for (User u : room) {
                sb.append(u.level).append(" ").append(u.name).append("\n");
            }
        }
        System.out.print(sb);
    }
    static class User {
        int level;
        String name;
        public User(int level, String name) {
            this.level = level;
            this.name = name;
        }
    }
}
[방법 3] 클래스
import java.io.*;
import java.util.*;
public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        // input
        StringTokenizer st = new StringTokenizer(br.readLine());
        int p = Integer.parseInt(st.nextToken()); // 플레이어 수
        int m = Integer.parseInt(st.nextToken()); // 방의 정원
        // 정보 저장
        List<User> userList = new ArrayList<>();
        for(int i=0; i<p; i++){
            st = new StringTokenizer(br.readLine());
            int l = Integer.parseInt(st.nextToken()); // 레벨
            String n = st.nextToken(); // 닉네임
            userList.add(new User(l, n));
        }
        List<Room> rooms = new ArrayList<>();
        // solve
        for(User user:userList) {
            boolean joined = false;
            // 기존 방 탐색 (레벨 범위, 정원 미만)
            for (Room room : rooms) {
                if (room.users.size() < m &&
                        user.level >= room.level - 10 &&
                        user.level <= room.level + 10) {
                    room.users.add(user);
                    joined = true;
                    break;
                }
            }
            // 못 들어가면 새 방 생성
            if (!joined) {
                Room newRoom = new Room(user.level);
                newRoom.users.add(user);
                rooms.add(newRoom);
            }
        }
        // 방 생성 순서대로 출력
        StringBuilder sb = new StringBuilder();
        for (Room room : rooms) {
            if (room.users.size() == m) sb.append("Started!\n");
            else sb.append("Waiting!\n");
            room.users.sort((a, b) -> a.name.compareTo(b.name));
            for (User u : room.users) {
                sb.append(u.level).append(" ").append(u.name).append("\n");
            }
        }
        System.out.print(sb);
    }
    public static class User {
        int level;
        String name;
        public User(int level, String name) {
            this.level = level;
            this.name = name;
        }
    }
    public static class Room {
        int level;
        ArrayList<User> users = new ArrayList<>();
        Room(int level) {
            this.level = level;
        }
    }
}
      
댓글남기기