IT recording...

[BOJ] 2517 달리기 - Java 본문

Algorithm

[BOJ] 2517 달리기 - Java

I-one 2022. 2. 4. 16:49

[원문링크]

https://adorable-aspen-d23.notion.site/BOJ-2517-3bfb4962163f45d190eb99a4fc962f72

 

[BOJ] 2517

코드

adorable-aspen-d23.notion.site

 

[풀이]

  • 조건 : 나보다 index가 작은 애들 중에 나보다 실력이 안좋은 애들 수
  • 인덱스 트리
    • 담는 순서 : 실력이 안좋은 애들 순으로 넣기
    • index : 애들 index 그대로
    • value : 나보다 index가 작으면서 실력이 안좋은 애들 수
  • 실력이 안좋은 애들부터 담으니까 그 앞에 몇개가 존재하는지를 찾으면 정답을 알 수 있다.

[코드]

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Comparator;
import java.util.StringTokenizer;

public class Boj2517_달리기 {
    static int N;
    static int[] indexTree;
    static Player[] player;
    static int treeSize, offset; //leaf노드 바로 전 index
    static int[] answer;

    public static void main(String[] args) throws Exception{
        System.setIn(new FileInputStream("src/main/java/input.txt"));
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        N = Integer.parseInt(br.readLine());
        treeSize = getTreeSize();
        indexTree = new int[treeSize];
        player = new Player[N+1];
        answer = new int[N+1];
        offset = (treeSize >> 1) - 1; //treeSize/2 - 1

        player[0] = new Player(0,0);
        for(int i=1;i<N+1;i++){
            player[i] = new Player(i,Integer.parseInt(br.readLine()));
        }

        Arrays.sort(player); //실력 안좋은 순으로 정렬

        for(int i=1;i<N+1;i++){
            //query(1,index) 진행하면 앞지를 수 있는 수 나옴
            int subValue = query(1,N,1,1,player[i].idx);
            answer[player[i].idx] = player[i].idx - subValue;

            //update 진행
            updateTree(1,N,1, player[i].idx,1);
        }

        StringBuilder sb = new StringBuilder();
        for(int i=1;i<N+1;i++){
            sb.append(answer[i]).append("\\n");
        }
        System.out.println(sb);
    }

    static int query(int start, int end, int index, int targetStart, int targetEnd){
        if(targetEnd < start || targetStart > end){
            return 0;
        }
        if(targetStart <= start && end <= targetEnd){
            return indexTree[index];
        }
        int mid = (start+end)/2;
        return query(start,mid,index*2,targetStart,targetEnd) + query(mid+1,end,index*2+1,targetStart,targetEnd);
    }

    static void updateTree(int start,int end, int index, int target, int diff){
      
        //범위가 아닐 때
        if(start > target || end < target){
            return;
        }
        indexTree[index] += diff;
        //leaf노드면 리턴
        if(start == end){
            return;
        }
        int mid = (start+end)/2;
        updateTree(start,mid,index*2,target,diff);
        updateTree(mid+1,end,index*2+1,target,diff);
        return;
    }

    static int getTreeSize(){
        int k=1; //2^K >= N 찾기
        while(k < N){
            k *= 2;
        }
        return k * 2;
    }

    static class Player implements Comparable<Player>{
        int idx;
        int value;

        public Player(int idx, int value) {
            this.idx = idx;
            this.value = value;
        }

        @Override
        public int compareTo(Player o) {
            return Integer.compare(this.value,o.value);
        }
    }
}

얻어가는 것

  • segment tree
  • StringBuilder의 중요성
    • System.out.println쓰니까 시간초과 나왔다.
    • 귀찮더라도 StringBuilder 사용 해보기..
StringBuilder sb = new StringBuilder();
sb.append(answer).append("\\n");

//출력
System.out.println(sb);

느낀점

"220201"

소요 시간 : 2h

  • segment tree

'Algorithm' 카테고리의 다른 글

[BOJ] 2573 빙산 - Java  (0) 2022.02.19
[BOJ] 7569 토마토 - Java  (0) 2022.02.17
[BOJ] 2014 소수의 곱 - Java  (0) 2022.02.04
[BOJ] 2904 수학은 너무 쉬워 - Java  (0) 2022.02.04
[BOJ] 2042 구간 합 구하기 - python  (0) 2021.12.21
Comments