[서버 증설 횟수] 코딩테스트 연습 > 2025 프로그래머스 코드챌린지 2차 예선 > 서버 증설 횟수
※ 주의 : 문제풀이 방법은 다양합니다. 참고만 해주세요 ※
[문제설명]
당신은 온라인 게임을 운영하고 있습니다. 같은 시간대에 게임을 이용하는 사람이 m명 늘어날 때마다 서버 1대가 추가로 필요합니다. 어느 시간대의 이용자가 m명 미만이라면, 서버 증설이 필요하지 않습니다. 어느 시간대의 이용자가 n x m명 이상 (n + 1) x m명 미만이라면 최소 n대의 증설된 서버가 운영 중이어야 합니다. 한 번 증설한 서버는 k시간 동안 운영하고 그 이후에는 반납합니다. 예를 들어, k = 5 일 때 10시에 증설한 서버는 10 ~ 15시에만 운영됩니다.
하루 동안 모든 게임 이용자가 게임을 하기 위해 서버를 최소 몇 번 증설해야 하는지 알고 싶습니다. 같은 시간대에 서버를 x대 증설했다면 해당 시간대의 증설 횟수는 x회입니다.
다음은 m = 3, k = 5 일 때의 시간대별 증설된 서버의 수와 증설 횟수 예시입니다.


모든 게임 이용자를 감당하기 위해 최소 7번 서버를 증설해야 하며, 이보다 적은 수의 서버 증설로는 모든 게임 이용자를 감당할 수 없습니다.
0시에서 23시까지의 시간대별 게임 이용자의 수를 나타내는 1차원 정수 배열 players, 서버 한 대로 감당할 수 있는 최대 이용자의 수를 나타내는 정수 m, 서버 한 대가 운영 가능한 시간을 나타내는 정수 k가 주어집니다. 이때, 모든 게임 이용자를 감당하기 위한 최소 서버 증설 횟수를 return 하도록 solution을 완성해 주세요.
제한사항
- players의 길이 = 24
- 0 ≤ players의 원소 ≤ 1,000
- players[i]는 i시 ~ i+1시 사이의 게임 이용자의 수를 나타냅니다.
- 1 ≤ m ≤ 1,000
- 1 ≤ k ≤ 24
테스트 케이스 구성 안내
아래는 테스트 케이스 구성을 나타냅니다. 각 그룹 내의 테스트 케이스를 모두 통과하면 해당 그룹에 할당된 점수를 획득할 수 있습니다.

입출력 예

입출력 예 설명
입출력 예 #1
- 문제의 예시와 같습니다.
입출력 예 #2
- 총 11번 서버를 증설해야 합니다.
- 3 ~ 4시: 2번
- 5 ~ 6시: 2번
- 7 ~ 8시: 3번
- 15 ~ 16시: 1번
- 18 ~ 19시: 2번
- 20 ~ 21시: 1번
입출력 예 #3
- 총 12번 서버를 증설해야 합니다.
- 5 ~ 6시: 2번
- 9 ~ 10시: 1번
- 11 ~ 12시: 5번
- 13 ~ 14시: 2번
- 15 ~ 16시: 1번
- 23 ~ 24시: 1번
[간단설명]
매시간 이용자 수에 따른 최소 서버 증설 횟수 구하기
[접근방법]
1. 큐를 만든다.
2. 현재 이용자수가 최대 이용자수보다 크면 서버를 증설한다.
2.1. 큐에 저장된 서버를 계산한다.
2.2. 증설개수가 0보다 크면 서버를 신규 증설한다.
3. 큐에 저장된 서버의 시간을 계산해준다.
4. 최소 서버 증설 횟수를 리턴한다.
[주의사항]
1. 리스트로 구현하면, size를 구할때, get, remove할 때, 원하는 데이터를 엑세스하기 쉽지 않다.
2. 큐나 우선순위큐를 사용해서 구현해보자.
[소스공개]
import java.util.*;
class Solution {
public int solution(int[] players, int m, int k) {
// 큐 만들기
Queue<int[]> que = new LinkedList<>();
int queSize = 0;
int queCnt = 0;
// 변수 선언
int maxPlayers = m; // 최대 이용자수
int totolServer = 0; // 최소 서버 증설 횟수
for(int p : players){
// 현재 이용자가 최대 이용자수보다 크거나 같으면
if(p>=maxPlayers){
int addServer = p/m; // 현재 필요한 서버
queSize = que.size();
queCnt = 0;
// 현재 필요한 서버에서, 큐에 저장된 서버만큼 빼준다
while(queCnt < queSize){
int[] now = que.poll();
addServer -= now[0];
que.add(now);
queCnt++;
}
// 새로 서버를 증설해야하면,
// 최소 서버 증설 횟수 증가, 최대 이용자수 증가
if(addServer>0){
que.add(new int[]{addServer,k});
totolServer+=addServer;
maxPlayers+=addServer*m;
}
}
queSize = que.size();
queCnt = 0;
// 큐의 서버에 저장된 대여 시간 계산
while(queCnt < queSize){
int[] now = que.poll();
now[1]-=1;
// 대여 시간 만료
if(now[1]==0){
maxPlayers-=now[0]*m;
}else{
// 아니면 -1 시간을 다시 큐에 넣어준다
que.offer(now);
}
queCnt++;
}
}
// 최소 서버 증설 횟수 리턴
return totolServer;
}
}
[실행결과]
'코딩 > 프로그래머스' 카테고리의 다른 글
[프로그래머스/JAVA] 코딩테스트 연습 > 연습문제 > 점 찍기 (by 다알쥐AI) (0) | 2025.02.26 |
---|---|
[프로그래머스/JAVA] 코딩테스트 연습 > 연습문제 > 우박수열 정적분(by 다알쥐AI) (1) | 2025.02.17 |
[프로그래머스/JAVA] 코딩테스트 연습 > 연습문제 > 하노이의 탑 (by 다알쥐AI) (1) | 2025.02.16 |
[프로그래머스/JAVA] 코딩테스트 연습 > 연습문제 > 가장 큰 정사각형 찾기 (by 다알쥐AI) (0) | 2025.02.15 |
[프로그래머스/JAVA] 코딩테스트 연습 > 2021 카카오 채용연계형 인턴십> 거리두기 확인하기 (by 다알쥐AI) (0) | 2025.02.12 |