본문 바로가기

PS/백준

[백준 #20006] 랭킹전 대기열 - JAVA(자바)

문제

종운이는 운영하던 게임에 랭킹전 기능을 추가하려고 한다. 플레이어 간의 실력차이가 있을 수 있기 때문에 입장을 신청하면 자신과 비슷한 레벨의 플레이어들을 매칭하여 게임을 시작하게 하려고 한다.

플레이어 간 매칭을 해주는 시스템은 다음과 같다.

  1. 플레이어가 입장을 신청하였을 때 매칭이 가능한 방이 없다면 새로운 방을 생성하고 입장시킨다. 이떄 해당 방에는 처음 입장한 플레이어의 레벨을 기준으로 -10부터 +10까지 입장 가능하다.
  2. 입장 가능한 방이 있다면 입장시킨 후 방의 정원이 모두 찰 때까지 대기시킨다.
    1. 이때 입장이 가능한 방이 여러 개라면 먼저 생성된 방에 입장한다.
  3. 방의 정원이 모두 차면 게임을 시작시킨다.

플레이어의 수 p, 플레이어의 닉네임 n, 플레이어의 레벨 l, 방 한개의 정원 m이 주어졌을 때 위와 같은 방법으로 매칭해주고 최종적으로 만들어진 방의 상태와 입장 플레이어들을 출력하는 프로그램을 작성하자.

https://www.acmicpc.net/problem/20006

 

코드

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

public class Main {

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringBuilder sb = new StringBuilder();
        StringTokenizer st = new StringTokenizer(br.readLine());
        int p = Integer.parseInt(st.nextToken());
        int m = Integer.parseInt(st.nextToken());
        ArrayList<Room> list = new ArrayList<>(); // 모든 방을 돌면서 레벨안에 들어가는지 확인해야 함.
        for (int i = 0; i < p; i++) {
            st = new StringTokenizer(br.readLine());
            int lv = Integer.parseInt(st.nextToken());
            String name = st.nextToken();
            Member member = new Member(lv, name);
            // 매칭이 가능한 방이 없으면 새로운 방 생성
            label : if(!list.isEmpty()){
                for (Room room : list) {
                    if(room.isOk(member) && !room.isFull()){ // 범위안에 들어가고 정원이 차지 않았을 때
                        room.addMember(member);
                        break label;
                    }
                }
                list.add(new Room(member, m)); // 모든 방을 봤을 때 들어갈 수 없는 경우
            }else{
                list.add(new Room(member, m)); // 방이 없는 경우
            }
        }
        for (Room room : list) {
            if (room.isFull()) {
                sb.append("Started!");
            }else{
                sb.append("Waiting!");
            }
            sb.append("\n");
            Collections.sort(room.list, (o1, o2) -> o1.name.compareTo(o2.name));
            for (Member member : room.list) {
                sb.append(member.lv).append(" ").append(member.name).append("\n");
            }
        }

        System.out.print(sb);
    }
}

class Room{
    List<Member> list = new ArrayList<>();
    int low;
    int high;
    int m;

    public Room(Member member, int m){
        list.add(member);
        this.low = member.lv - 10;
        this.high = member.lv + 10;
        this.m = m;
    }

    public void addMember(Member member) {
        list.add(member);
    }

    public boolean isOk(Member member) {
        if (member.lv < low || member.lv > high) {
            return false;
        }
        return true;
    }

    public boolean isFull() {
        return list.size() >= m;
    }
}

class Member{
    int lv;
    String name;

    public Member(int lv, String name) {
        this.lv = lv;
        this.name = name;
    }
}