
N개의 팀이 K개의 문제를 푼다고 한다.
각각의 팀이 받은 점수의 총합으로 등수를 나눈다고 할 때,
내가 속한 T팀의 등수는 몇등인가?
단, 두 팀의 점수가 같을 경우 다음 규칙에 의해서 순위가 정해진다.
- 최종 점수가 같은 경우, 풀이를 제출한 횟수가 적은 팀의 순위가 높다.
- 최종 점수도 같고 제출 횟수도 같은 경우, 마지막 제출 시간이 더 빠른 팀의 순위가 높다.
각각의 팀에 대한 정보를 저장할 Team 클래스를 만들었다.
Team 클래스는 아래와 같은 요소를 가지고 있다.
score 배열cntlastOrder그 외에도 풀이를 제출하면 score에 저장을 할 함수 SetScore()을 만들었고
최종적으로 비교를 위해 정보를 리턴해줄 GetTatal() 함수를 만들었다.
Team class
class Team {
constructor(length) {
// 점수 저장 배열
this.score = new Array(length).fill(0);
// 풀이 제출 횟수
this.cnt = 0;
// 마지막 제출 시기
// 10,000개의 로그가 최대이기 때문에 10,000으로 초기화.
this.lastOrder = 10000;
}
// 점수 저장 함수
SetScore(Num, Score, LastOrder) {
// 제출한 점수가 높을 때만 갱신.
if (this.score[Num - 1] < Score) {
this.score[Num - 1] = Score;
}
// 제출 횟수 증가
this.cnt++;
// 제출 시기 갱신.
this.lastOrder = LastOrder;
}
// 정보 리턴
GetTotal() {
// 점수 총합.
let total = this.score.reduce((acc, cur) => {
return acc + cur;
}, 0);
// 점수 총합, 제출 횟수, 마지막 제출 시기
return [total, this.cnt, this.lastOrder];
}
}
이후에는 간단하다.
각각의 팀 정보를 저장할 배열에 팀 객체를 넣어주면 된다.
예시를 들면 [new Team(), new Team(), .....] 이런식이다.
이제 각각의 로그를 확인하여 점수를 갱신한 후에 T팀보다 점수가 높은 팀이 몇개인지 세주면 된다.
등수 계산 함수
const CalculateMyScore = (N, K, T, M) => {
// 로그 저장.
const SubmitLists = input.splice(0, M).map(v => v.split(' ').map(Number));
// 팀 갯수만큼 배열 생성.
const Teams = new Array(N);
// 등수
let answer = 1;
for (let i = 0; i < Teams.length; i++) {
Teams[i] = new Team(K);
}
// 로그 확인 후 각각의 팀에 점수 갱신.
for (let i = 0; i < SubmitLists.length; i++) {
const [TeamId, Num, Score] = SubmitLists[i];
Teams[TeamId - 1].SetScore(Num, Score, i);
}
// 내팀의 점수
const My = Teams[T - 1].GetTotal();
// 우리팀보다 높은 점수의 팀 확인.
for (let i = 0; i < Teams.length; i++) {
if (i !== T - 1) {
const Compare = Teams[i].GetTotal();
if (Compare[0] > My[0]) {
answer++;
continue;
} else if (Compare[0] === My[0]) {
if (Compare[1] < My[1]) {
answer++;
continue;
} else if (Compare[1] === My[1]) {
if (Compare[2] < My[2]) {
answer++
continue;
}
}
}
}
}
return answer;
};
이제 테스트 케이스만큼 위의 함수를 진행시킬 함수를 생성하면 끝이다.
전체 코드
let fs = require("fs");
let input = fs.readFileSync("/dev/stdin").toString().trim().split("\n");
const TestCase = parseInt(input.shift());
class Team {
constructor(length) {
// 점수 저장 배열
this.score = new Array(length).fill(0);
// 풀이 제출 횟수
this.cnt = 0;
// 마지막 제출 시기
// 10,000개의 로그가 최대이기 때문에 10,000으로 초기화.
this.lastOrder = 10000;
}
// 점수 저장 함수
SetScore(Num, Score, LastOrder) {
// 제출한 점수가 높을 때만 갱신.
if (this.score[Num - 1] < Score) {
this.score[Num - 1] = Score;
}
// 제출 횟수 증가
this.cnt++;
// 제출 시기 갱신.
this.lastOrder = LastOrder;
}
// 정보 리턴
GetTotal() {
// 점수 총합.
let total = this.score.reduce((acc, cur) => {
return acc + cur;
}, 0);
// 점수 총합, 제출 횟수, 마지막 제출 시기
return [total, this.cnt, this.lastOrder];
}
}
const CalculateMyScore = (N, K, T, M) => {
// 로그 저장.
const SubmitLists = input.splice(0, M).map(v => v.split(' ').map(Number));
// 팀 갯수만큼 배열 생성.
const Teams = new Array(N);
// 등수
let answer = 1;
for (let i = 0; i < Teams.length; i++) {
Teams[i] = new Team(K);
}
// 로그 확인 후 각각의 팀에 점수 갱신.
for (let i = 0; i < SubmitLists.length; i++) {
const [TeamId, Num, Score] = SubmitLists[i];
Teams[TeamId - 1].SetScore(Num, Score, i);
}
// 내팀의 점수
const My = Teams[T - 1].GetTotal();
// 우리팀보다 높은 점수의 팀 확인.
for (let i = 0; i < Teams.length; i++) {
if (i !== T - 1) {
const Compare = Teams[i].GetTotal();
if (Compare[0] > My[0]) {
answer++;
continue;
} else if (Compare[0] === My[0]) {
if (Compare[1] < My[1]) {
answer++;
continue;
} else if (Compare[1] === My[1]) {
if (Compare[2] < My[2]) {
answer++
continue;
}
}
}
}
}
return answer;
};
const solution = () => {
let answer = [];
// 테스트 케이스만큼 진행.
for (let i = 0; i < TestCase; i++) {
const [N, K, T, M] = input.shift().split(' ').map(Number);
answer.push(CalculateMyScore(N, K, T, M));
}
console.log(answer.join('\n'));
};
solution();
이렇게 코드를 제출하고 다른 사람들의 풀이를 확인해 보니 다들 나보다 코드 줄 수가 적었다. 그러나 전체적인 풀이는 비슷했고 개인적으로 내 코드가 더 마음에 들어서 굳이 수정하지는 않았다. 실력을 더 닦고 나서 다시 확인한 후에 내 코드가 수정이 필요하다고 생각하면 그때 수정할듯하다.