백준

백준 정렬 - 18870번 : 좌표 압축

맴썰 2022. 2. 10. 17:08

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

 

18870번: 좌표 압축

수직선 위에 N개의 좌표 X1, X2, ..., XN이 있다. 이 좌표에 좌표 압축을 적용하려고 한다. Xi를 좌표 압축한 결과 X'i의 값은 Xi > Xj를 만족하는 서로 다른 좌표의 개수와 같아야 한다. X1, X2, ..., XN에 좌

www.acmicpc.net


import java.util.*;
import java.io.*;
public class Main {
	public static int[] sorted;
	public static void main(String[] args) throws IOException{
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[] a = new int[n];
        int[] b = new int[n];
        for(int i=0; i<n; i++){
            a[i] = sc.nextInt();
            b[i] = a[i];
        }
        sorted = new int[n];
        merge_sort(a,0,n-1);
        HashMap<Integer,Integer> hm = new HashMap<>();
        int idx = 0;
        for(int i=0; i<n; i++) {
        	if(hm.get(a[i])==null) {
        		hm.put(a[i], idx++);
        	}
        }
        for(int i=0; i<n; i++) {
        	b[i] = hm.get(b[i]);
        }
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        for(int i=0; i<sorted.length; i++) {bw.write(b[i]+"\n");}
        bw.close();
    }
	public static void merge_sort(int[] a, int i, int j) {
		if(i==j) return;
		int mid = (i+j)/2;
		merge_sort(a,i,mid);
		merge_sort(a,mid+1,j);
		merge(a,i,mid,j);
	}
	public static void merge(int[] a,int i, int mid, int j) {
		int idx = i;
		int start = i;
		int target = mid+1;
		while(start<=mid&&target<=j) {
			if(a[start]<=a[target]) {
				sorted[idx++] = a[start];
				start++;
			}
			else if(a[start]>a[target]){
				sorted[idx++] = a[target];
				target++;
			}
		}
		
		while(start<=mid) {
			sorted[idx++] = a[start];
			start++;
		}
		while(target<=j) {
			sorted[idx++] = a[target];
			target++;
		}
		for(int k = i; k<=j; k++) {
			a[k] = sorted[k]; 
		}
	}
}