Softeer - 성적평가

leehyunjon·2023년 1월 11일
0

Algorithm

목록 보기
157/162

성적 평가 : https://softeer.ai/practice/info.do?idx=1&eid=1309


Problem


Solve

3개의 대회에서 등수와 총 등수를 구해야하는 문제입니다.

먼저 각 대회에서의 점수를 얻은 후 참가자와 참가자의 등수를 담은 우선순위 큐를 만들어줍니다.
총 등수를 구하기 위해 해당 참가자의 등수도 저장해줍니다.

해당 대회에서 점수가 동일하다면 동일한 점수에서 가장 큰 등수로 동일한 등수로 선언해줍니다.
우선순위 큐는 점수를 기준으로 내림차순 정렬되어있기 때문에 높은 점수 순으로 탐색하여 이전에 나온 점수와 동일한지 확인합니다. 점수가 동일하다면 동일한 점수를 카운트(sameCount)해주다가 이전 점수와 다른 점수가 나올때 등수를 카운트한 값을 더하여 새로운 등수를 갱신하여 저장해줍니다.

이때 해당 대회에서 가장 점수가 높은 참가자를 우선순위 큐에서 꺼내어 이전 점수를 갱신해줍니다.
그래야 다음 참가자의 점수와 비교하여 등수를 구할 수 있습니다.

	static int[] getGrade(PriorityQueue<Participant> pq){
    	//각 참가자의 등수
		int[] grades = new int[N];

		//초기 등수를 1, 이전 점수를 해당 대회에서 가장 높은 점수를 꺼내어 초기화 해줍니다.
		Participant first = pq.poll();
		int grade = 1;
		int prevPoint = first.point;
        //이전 점수와 동일한 개수입니다.
		//이전 점수와 동일하다면 하나씩 증가시켜줍니다.
		int sameCount = 1;

		grades[first.idx] = grade;

		//두번째로 높은 점수부터 반복하며 등수를 갱신해줍니다.
		while(!pq.isEmpty()){
			Participant participant = pq.poll();

			//이전 점수와 현재 참가자의 점수가 동일하지 않다면 등수를 변경하여 등록해주어야합니다.
            //현재까지 해당 점수의 참가자 수를 grade에 더하여 갱신해줍니다.
            //해당 점수는 현재까지 해당 참가자 한명만 가지고 있기 때문에 sameCount를 1로 초기화합니다.
			if(prevPoint != participant.point){
				grade += sameCount;
				sameCount = 1;
			}
            //이전 점수와 동일하다면 동일한 점수를 가지고 있기 때문에 sameCount를 증가시켜줍니다.
			else{
				sameCount++;
			}

			//해당 참가자의 등수를 선언해줍니다.
			grades[participant.idx] = grade;
            //다음 참가자의 점수와 비교하기 위해 이전 점수를 현재 참가자의 점수로 갱신시켜줍니다.
			prevPoint = participant.point;
		}

		return grades;
	}

Code

public class Main
{
	static int N;
	public static void main(String args[])
		throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

		N = Integer.parseInt(br.readLine());
		int[] totalPoint = new int[N];

		StringBuilder sb = new StringBuilder();

		for(int c=0;c<3;c++){
			PriorityQueue<Participant> pq = new PriorityQueue<>();

			StringTokenizer st = new StringTokenizer(br.readLine()," ");
			for(int i=0;i<N;i++){
				int point = Integer.parseInt(st.nextToken());

				pq.offer(new Participant(i,point));
				totalPoint[i] += point;
			}

			int[] grades = getGrade(pq);

			for(int i=0;i<N;i++){
				sb.append(grades[i]).append(" ");
			}
			sb.append("\n");
		}


		PriorityQueue<Participant> pq = new PriorityQueue<>();
		for(int i=0;i<N;i++){
			pq.offer(new Participant(i, totalPoint[i]));
		}

		int[] grades = getGrade(pq);

		for(int i=0;i<N;i++){
			sb.append(grades[i]).append(" ");
		}

		bw.write(sb.toString());
		bw.flush();
		bw.close();
	}

	static int[] getGrade(PriorityQueue<Participant> pq){
		int[] grades = new int[N];

		Participant first = pq.poll();
		int grade = 1;
		int prevPoint = first.point;
		int sameCount = 1;

		grades[first.idx] = grade;

		while(!pq.isEmpty()){
			Participant participant = pq.poll();

			if(prevPoint != participant.point){
				grade += sameCount;
				sameCount = 1;
			}
			else{
				sameCount++;
			}

			grades[participant.idx] = grade;
			prevPoint = participant.point;
		}

		return grades;
	}

	static class Participant implements Comparable<Participant>{
		int idx;
		int point;

		public Participant(int idx, int point){
			this.idx = idx;
			this.point = point;
		}

		@Override
		public int compareTo(Participant o){
			return o.point - this.point;
		}
	}
}

Result


Reference

profile
내 꿈은 좋은 개발자

1개의 댓글

comment-user-thumbnail
2023년 2월 16일

안녕하세요! 저도 softeer 문제 java로 풀다가 막히는 부분이 있어서 이 블로그에서 정보 얻어가며 해결하고 있습니다. 좋은 코드 올려주셔서 감사합니다. :)
혹시 이 문제 코드에서 PriorityQueue 를 사용하셨는데 이건 정렬 시 시간복잡도가 어떻게 되는지 아실까요? 저는 병합정렬 이용해서 풀어보려했는데 계속 시간초과가 나서ㅠㅠ 시간되실때 답변 주시면 감사하겠습니다!

답글 달기