(백준) 달리기_2517

2022. 2. 2. 16:22·알고리즘/백준

https://www.acmicpc.net/problem/2517

 

🐢 설명

자신보다 느린 사람이 앞에 있다면 모두 추월할 수 있다는 가정하에 최대 몇등을 기대할 수 있는지 계산하면 되는 문제이다. 세그먼트 트리를 이용해서 풀 수 있다.

 

<기존 달리고 있는 순서>

능력 : 2, 8, 10, 7, 1, 9, 4, 15

순서 : 1, 2,  3,  4, 5, 6, 7,  8

 

<능력순>

능력 : 15, 10, 9, 8, 7, 4, 2, 1

순서 :  8,  3,  6, 2, 4, 7, 1, 5

 

1. 먼저 현재 달리고 있는 사람들의 순서 + 능력을 기록한다.

2. 이들 각각은 자신의 앞에 있는 자신보다 능력이 높은 사람의 수 + 1 등이 최대 기대 등수 임을 알 수 있다.

3. 위 정보를 가지고 능력순으로 정렬한다. (능력값이 클수록 능력이 좋다) 이 배열을 능력순배열이라고 하자.

4.1~N번 능력순 배열에 접근해서 해당 인덱스에 있는 사람의 인덱스를 확인하고 그 인덱스를 가지고 기대 되는 등수 배열에 Q(1, 구한 인덱스)를 통해 앞에 존재하는 인원수를 구하고, 인원수 + 1을 기록한다.

 

즉, 능력 순으로 접근하므로 자신의 앞에 기록된 사람 수는 절대로 추월을 못함을 알고 있으므로 1~자신의 인덱스 사이의 모든 사람 수 + 1이 자신의 등수가 된다. 또한 능력이 떨어지는 사람도 1번에서 달리고 있다면 앞에 사람이 없으므로 1등이 예상된다. 따라서 1~1사이의 사람수를 세면 0이 되어 1등을 할것이라 예상하게 된다.

 

예제를 참고해 보면 1 ~ N명의 사람들에 대해 인덱스를 가지고 능력순배열에 접근한다. 능력순배열[1]에 담긴 사람의 인덱스를 확인한다. 가장 능력이 좋은 15 능력을 가진 8번이 1번에 있을 것이므로 8이 반환된다. 그럼 1~8번 사이의 사람 수를 세고, 그 수 + 1을 등수로 기록한다. 사람수 배열에는 1을 추가해준다.

 

🐢코드
package 인덱스트리;

import java.io.*;
import java.util.*;

public class 달리기_2517 {
	static int N;
	static int S;
	static Runner[] runnersSkillOrder;
	static int[] tree;
	static int[] runnerResult;
	static StringBuilder answer = new StringBuilder();

	public static void main(String[] args) throws Exception {
	    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

		N = Integer.parseInt(br.readLine());
		runnersSkillOrder = new Runner[N + 1];
		runnerResult = new int[N + 1];
		S = 1;
		while (S < N) S *= 2;
		tree = new int[S * 2];

		runnersSkillOrder[0] = new Runner(0, 1111111111);
		for (int i = 1; i < N + 1; i++) {
			int skill = Integer.parseInt(br.readLine());
			runnersSkillOrder[i] = new Runner(i, skill);
		}
		Arrays.sort(runnersSkillOrder, Comparator.comparingInt(R -> -R.skill));

		segmentTree();

		for (int order = 1; order < N + 1; order++) {
			answer.append(runnerResult[order]).append("\n");
		}
        
		System.out.print(answer);
	}

	private static void segmentTree() {
		for (int i = 1; i < N + 1; i++) {

			int runnerOrder = i;
			Runner runner = runnersSkillOrder[runnerOrder];

			if (runner.order == runnerOrder) {
				int count = query(1, 1, S, 1, runnerOrder);
				runnerResult[runnerOrder] = count + 1;
			} else {
				runnerOrder = runner.order;
				int count = query(1, 1, S, 1, runnerOrder);
				runnerResult[runnerOrder] = count + 1;
			}

			update(runnerOrder);
		}
	}

	private static void update(int node) {
		int cur = S + node - 1;

		while (cur >= 1) {
			tree[cur] += 1;
			cur /= 2;
		}
	}

	private static int query(int node, int start, int end, int queryLeft, int queryRight) {
		if (start > queryRight || end < queryLeft) return 0;

		if (start == end) return tree[node];

		if (queryLeft <= start && end <= queryRight) return tree[node];

		int mid = (start + end) / 2;
		return query(node * 2, start, mid, queryLeft, queryRight) +
				query(node * 2 + 1, mid + 1, end, queryLeft, queryRight);
	}

	private static class Runner{
		int order;
		int skill;

		public Runner(int order, int skill) {
			this.order = order;
			this.skill = skill;
		}
	}
}
🐢 마무리
반응형
저작자표시 비영리 변경금지 (새창열림)

'알고리즘 > 백준' 카테고리의 다른 글

(백준) 트리의 독립집합 _ 2213  (0) 2022.03.27
백준) 스위치_1395  (2) 2022.02.02
(백준) 강수량 _ 2094  (0) 2022.02.02
(백준) 점심메뉴 _ 12099  (0) 2021.12.29
(백준) 제기차기 _ 23830  (1) 2021.12.28
'알고리즘/백준' 카테고리의 다른 글
  • (백준) 트리의 독립집합 _ 2213
  • 백준) 스위치_1395
  • (백준) 강수량 _ 2094
  • (백준) 점심메뉴 _ 12099
구름뭉치
구름뭉치
구름의 개발일기장
  • 구름뭉치
    구름 개발일기장
    구름뭉치
  • 전체
    오늘
    어제
    • ALL (283)
      • 프로젝트 (23)
        • 토스페이먼츠 PG 연동 시리즈 (12)
        • JWT 방식 인증&인가 시리즈 (6)
        • 스우미 웹 애플리케이션 프로젝트 (1)
        • 스프링부트 기본 보일러 플레이트 구축 시리즈 (2)
        • 마이크로서비스 아키텍쳐 시리즈 (1)
      • 스프링 (43)
        • 스프링부트 API 설계 정리 (8)
        • 스프링부트 RestAPI 프로젝트 (18)
        • 스프링부트 WebSocket 적용기 (3)
        • 스프링 JPA 정리 시리즈 (5)
        • 스프링 MVC (5)
        • 스프링 배치 (2)
        • 토비의 스프링 정리 (2)
      • 기술 학습 (28)
        • 아파치 카프카 (9)
        • 클린 코드 (4)
        • 디자인 패턴의 아름다움 (2)
        • 모던 자바 인 액션 (7)
        • JVM 스레드 딥다이브 (6)
      • Web (25)
        • 정리글 (20)
        • GraphQL 정리글 (2)
        • Jenkins 정리글 (3)
      • 취업 (6)
      • CS (77)
        • 네트워크 전공 수업 정리 (11)
        • OSI 7계층 정리 (12)
        • 운영체제 정리 (19)
        • 데이터베이스 정리 (5)
        • MySql 정리 (17)
        • GoF의 Design Pattern 정리 (12)
      • 알고리즘 (70)
        • 백준 (56)
        • 프로그래머스 (12)
        • 알고리즘 정리본 (1)
      • 기초 지식 정리 (2)
      • 일상 (8)
  • 블로그 메뉴

    • 홈
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    마우스 패드
    동유럽
    키보드 손목 받침대
    류블라냐
    mx master s3 for mac
    크로아티아
    레이저
    마우스
    부다페스트
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
구름뭉치
(백준) 달리기_2517
상단으로

티스토리툴바