개발자 톡
연습문제 톡
[21년 재직자 대회 예선] 로드 밸런서 트래픽 예측
JS
- 등록일
- 2024-11-14 15:34:57
- 조회수
- 35
- 작성자
- vavoya6324
이 문제 정말 미치는 줄 알았습니다.
분명 설계 잘한거 같은데... 강의 영상을 보고 설계를 비교해도 똑같은거 같은데... 왜 계속 틀리는지.
혹시 싶어서 문제 입력 범위를 보니 들어오는 요청 최대치가 10^18 이 설정되어있는게 보였습니다. 10^16 부터 JS는 BigInt로 설정을 해줘야하기에 그렇게 바꿨습니다.
다행스럽게도 통과되었습니다.
class FIFO { constructor(...values) { this.head = null this.tail = null this.length = 0 values.forEach((value, index) => { this.add(value) }) } add(value) { if (this.length > 0) { this.tail[1] = [value, null] this.tail = this.tail[1] } else { this.head = this.tail = [value, null] } this.length++ } pop() { if (this.length > 0) { const returnValue = this.head[0] this.head = this.head[1] this.length-- return returnValue } else return null } } const fs = require('fs'); const input = fs.readFileSync('input.txt', 'utf8').trim().split(/\n+/); // N: 서버 개수, K: 요청 개수 const [n, K] = input[0].trim().split(/\s+/).map(BigInt); const serverList = input.slice(1).map(server => server.trim().split(/\s+/).map(Number)); const N = Number(n) const requestCount = Array(N).fill(0n); const parentServerCounts = Array(N).fill(0); serverList.forEach(server => { for (let i = 1; i <= server[0]; i++) { const serverNum = server[i] parentServerCounts[serverNum - 1]++; } }) function processNextServer(serverNum, receivedRequestCount) { requestCount[serverNum - 1] += BigInt(receivedRequestCount); // 전달 받은 요청 개수 저장 parentServerCounts[serverNum - 1]--; // 진입 차수 감소 return parentServerCounts[serverNum - 1] === 0 } function passRequestToNextServer(serverNum, fifoList) { const totalRequest = requestCount[serverNum - 1]; // 받은 전체 요청 const nextServerCount = serverList[serverNum - 1][0]; // 다음 서버 개수 if (nextServerCount === 0) return const commonRequestCount = totalRequest / BigInt(nextServerCount) // 공통 전달 개수 const remainderCount = totalRequest % BigInt(nextServerCount) // 추가 전달 개수 // 다음 서버 탐색 시작 for (let i = 1; i <= nextServerCount; i++) { const nextServerNum = serverList[serverNum - 1][i]; // 다음 서버 번호 const isAllParentsProcessed = processNextServer(nextServerNum, commonRequestCount + BigInt(remainderCount >= i ? 1 : 0)) if (isAllParentsProcessed) { fifoList.add(nextServerNum) } } } function bfs(serverNum) { const fifoList = new FIFO(serverNum) while (fifoList.length > 0) { const currentServerNum = fifoList.pop() passRequestToNextServer(currentServerNum, fifoList); } } requestCount[0] = K bfs(1) console.log(requestCount.join(' ')) /* 서버에 r, x 값이 주어짐. P도 주어짐. x번째 P의 값이 타겟 서버 번호 r은 P의 개수, 전달 가능한 서버의 개수를 의미. r이 없으면 전달 할 서버가 없으니 워커 노드가 됨 P는 전달 서버 번호. x 를 통해 선택됨. x 초기값은 1 x는 r을 통해 갱신됨. 요청 하나 처리할 때 마다 (x mod r) + 1 Q. 1개씩 시뮬레이션이 되는가? A. 1 ≤ K ≤ 10^18 의 요청을 처리해야하고, 깊이 또한 고려해야함. 불가능 Q. 요청을 몇개 받았는지가 중요하니. 그냥 x, r 을 통해서 한번에 다 보내 버리면 안되나? A. (x mod r) + 1 은 그냥 서버 노드를 순회한다고 보면 된다. x는 1로 초기화되는 조건이니, 처음부터 시작함. r은 P의 개수, 그래서 K // r 이 각 노드 별로 전달되는 공통 요청 개수 이고, k % r이 0, 1, 2 면 0, P1, P1 ~ P2 에 추가 요청 1개씩 전달 Q. 그렇게하면 시간 복잡도는? A. 그냥 DFS? 순환 없다고 되어있고, 하나의 서버가 여러 서버로 부터 입력을 받을 수 있긴한데 간선이 500,000개라고 주어져 있으니... 위상 정렬을 섞어서 하자 요청 수: 6 서버 정보: 3 2 5 8 6 / 3 = 2 (2, 5, 8 서버에 2개씩) 6 % 3 = 0 (추가 요청 전달 없음) */
#[21년_재직자_대회_예선]_로드_밸런서_트래픽_예측
#js