Optimal Solution
[백준, C++] 20006 - 랭킹전 대기열 본문
https://www.acmicpc.net/problem/20006
20006번: 랭킹전 대기열
모든 생성된 방에 대해서 게임의 시작 유무와 방에 들어있는 플레이어들의 레벨과 아이디를 출력한다. 시작 유무와 플레이어의 정보들은 줄 바꿈으로 구분되며 레벨과 아이디는 한 줄에서 공백
www.acmicpc.net
문제 분석
플레이어가 방을 찾으러 들어가야 한단다. 근데 플레이어의 레벨이 방장의 레벨 +- 10의 범위 안에 있어야 방에 입장할 수 있단다(하긴 뭐 무작정 들어갈 수 있으면 그게 랭크게임인가). 당연하게도 방이 꽉 차면 레벨 조건이 맞아도 들어갈 수 없다. 플레이어가 들어갈 수 있는 방이 없는 경우에는 자신이 직접 방장이 된다.
이런 식으로 해서 플레이어가 주어졌을 때, 여러 방이 생길테고, 어떤 방은 정원이 차서 게임을 시작할거고 어떤 방은 정원이 안 차서 대기할 것이다. 그러면 방이 생성된 순서대로 방의 상태(Started or Waiting)와, 해당 방에 있는 플레이어의 레벨, 닉네임을 닉네임 사전순으로 출력하면 문제를 해결할 수 있다.
코드
#include <iostream>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;
struct Player {
int level;
string nickname;
Player(int level, string nickname) {
this->level = level;
this->nickname = nickname;
}
};
struct Room {
int level;
vector<Player> players;
Room(int level, Player roomOwner) {
this->level = level;
this->players = vector<Player>();
this->players.push_back(roomOwner);
}
};
int p, m;
int l;
string n;
vector<Room> rooms;
bool compare(Player player1, Player player2) {
return player1.nickname < player2.nickname;
}
void addPlayer(Player player) {
for (int i = 0; i < rooms.size(); i++) {
if (rooms[i].level + 10 >= player.level && rooms[i].level - 10 <= player.level && rooms[i].players.size() < m) {
rooms[i].players.push_back(player);
return;
}
}
rooms.push_back(Room(l, player));
}
void printResult() {
for (Room room : rooms) {
if (room.players.size() == m) {
cout << "Started!\n";
} else {
cout << "Waiting!\n";
}
sort(room.players.begin(), room.players.end(), compare);
for (Player player : room.players) {
cout << player.level << " " << player.nickname << "\n";
}
}
}
int main() {
cin.tie(NULL);
ios::sync_with_stdio(false);
cin >> p >> m;
for (int i = 0; i < p; i++) {
cin >> l >> n;
addPlayer(Player(l, n));
}
printResult();
return 0;
}
코드 설명
원래 알고리즘 풀 때 굳이 함수를 잘 나누지 않는 편이었고, 자료형도 굳이 구조체나 클래스로 정의하지 않고 pair를 무지성으로 남발했는데, 딱히 좋은 습관은 아닌 것 같단 생각이 들었다. 개발할 때는 변수명 하나도 그렇게 세심하게 고민하고 또 고민하는데, 왜 알고리즘은 대충 짜지 하는 생각이 들기도 했고, 무엇보다 내가 옛날에 짠 코드를 나조차도 이해를 못하는 걸 보니 좀 '공들여' 짜야겠다고 생각했다.
각설하고, 두 개의 구조체 Player와 Room을 만들었다. 나는 이 두 구조체를 활용해 문제를 풀었다.
사실 알고리즘을 설명할 것도 없는데, 이 문제는 내가 만든 단 2개의 메서드로 풀린다. addPlayer()와 printResult()이다.
addPlayer() 메서드는 Player를 인자로 받아서, 해당 Player가 들어갈 수 있는 Room이 있는지를 찾는다. 들어갈 수 있는 Room이 있다면 넣어주고, 그렇지 않다면 Room을 새로 생성하는 메서드이다. Player를 Room에 넣을 수 있는 조건은 별로 까다롭지 않기 때문에 굳이 설명하지 않는다.
printResult() 메서드는 Room에 정원이 가득 찼는지 여부를 확인해서 Started 나 Waiting 중 하나를 출력을 먼저 한다. 그리고 문제 본문의 출력 설명 중 닉네임은 '사전순으로 앞서는 플레이어부터' 출력하라고 했는데 이 부분을 놓쳐서 처음에 제출했을 때 틀렸습니다 라고 떴다. 문제를 오늘도 대충 읽었다. 사전순으로 앞서는 플레이어부터 출력하기 위해 Room 안에 있는 players 벡터를 정렬해줬다. compare 메서드는 직접 작성했다.
난이도가 실버 2라고 되어있는데 이게 왜 실버 2인지 잘 모르겠다. 단순한 구현인데 . . .
'알고리즘' 카테고리의 다른 글
[백준, C++] 1138 - 한 줄로 서기 (0) | 2023.09.04 |
---|---|
[백준, C++] 2075 - N번째 큰 수 (0) | 2023.09.01 |
[백준, C++] 11501 - 주식 (0) | 2023.09.01 |
[백준, C++] 2304 - 창고 다각형 (0) | 2023.09.01 |
[백준, C++] 19637 - IF문 좀 대신 써줘 (0) | 2023.08.31 |