[Algorithm] ๐Ÿ’ ๋ฐฑ์ค€ 2261 ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ๋‘ ์ 

HaJingJingยท2021๋…„ 4์›” 22์ผ
0

Algorithm

๋ชฉ๋ก ๋ณด๊ธฐ
18/119

0. ๋ฌธ์ œ

2์ฐจ์› ํ‰๋ฉด์ƒ์— n๊ฐœ์˜ ์ ์ด ์ฃผ์–ด์กŒ์„ ๋•Œ, ์ด ์ ๋“ค ์ค‘ ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ๋‘ ์ ์„ ๊ตฌํ•˜๋Š” ํ”„๋กœ๊ทธ๋žจ์„ ์ž‘์„ฑํ•˜์‹œ์˜ค.

์ž…๋ ฅ
์ฒซ์งธ ์ค„์— ์ž์—ฐ์ˆ˜ n(2 โ‰ค n โ‰ค 100,000)์ด ์ฃผ์–ด์ง„๋‹ค. ๋‹ค์Œ n๊ฐœ์˜ ์ค„์—๋Š” ์ฐจ๋ก€๋กœ ๊ฐ ์ ์˜ x, y์ขŒํ‘œ๊ฐ€ ์ฃผ์–ด์ง„๋‹ค. ๊ฐ๊ฐ์˜ ์ขŒํ‘œ๋Š” ์ ˆ๋Œ“๊ฐ’์ด 10,000์„ ๋„˜์ง€ ์•Š๋Š” ์ •์ˆ˜์ด๋‹ค. ์—ฌ๋Ÿฌ ์ ์ด ๊ฐ™์€ ์ขŒํ‘œ๋ฅผ ๊ฐ€์งˆ ์ˆ˜๋„ ์žˆ๋‹ค.

์ถœ๋ ฅ
์ฒซ์งธ ์ค„์— ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ๋‘ ์ ์˜ ๊ฑฐ๋ฆฌ์˜ ์ œ๊ณฑ์„ ์ถœ๋ ฅํ•œ๋‹ค.

1. ๋ฌธ์ œ ๊ฐ„๋‹จ ํ•ด์„

x, y์˜ ๊ฑฐ๋ฆฌ๋ฅผ ๊ณ„์‚ฐํ•˜์—ฌ ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ๋‘ ์  ์‚ฌ์ด ๊ฑฐ๋ฆฌ์˜ ์ œ๊ณฑ์„ ์ถœ๋ ฅ

2. ์•„์ด๋””์–ด

๋ถ„ํ• ์ •๋ณต
d ๋ณด๋‹ค ์ž‘์€ x๊ฐ„์˜ ๊ฑฐ๋ฆฌ๋ฅผ ๊ฐ€์ง„ point๋ฅผ ์ƒˆ๋กœ์šด ๋ฐฐ์—ด์— ์ €์žฅ
d๋ณด๋‹ค ์ž‘์€ y๊ฐ„์˜ ๊ฑฐ๋ฆฌ๋ฅผ ๊ฐ€์ง„ point์ด๋ฉด, x,y์ขŒํ‘œ์˜ ์ฐจ์ด๋ฅผ ๊ตฌํ•จ

3. ํ•ต์‹ฌ ํ’€์ด

1) ๋ถ„ํ• ์ •๋ณต

int mid = (start + end) / 2;

int d = Math.min(closestPair(arrList, start, mid), closestPair(arrList, mid + 1, end));

2) d ๋ณด๋‹ค ์ž‘์€ x๊ฐ„์˜ ๊ฑฐ๋ฆฌ๋ฅผ ๊ฐ€์ง„ point๋ฅผ ์ƒˆ๋กœ์šด ๋ฐฐ์—ด์— ์ €์žฅ

for (int i = start; i <= end; i++) {
			int t = arrList.get(mid).x - arrList.get(i).x;

			if (t * t < d) {
				band.add(arrList.get(i));
			}
	}

3) d๋ณด๋‹ค ์ž‘์€ y๊ฐ„์˜ ๊ฑฐ๋ฆฌ๋ฅผ ๊ฐ€์ง„ point์ด๋ฉด, x,y์ขŒํ‘œ์˜ ์ฐจ์ด๋ฅผ ๊ตฌํ•จ

for (int i = 0; i < band.size() - 1; i++) {
			for (int j = i + 1; j < band.size(); j++) {
				int t = band.get(j).y - band.get(i).y;

				if (t * t < d) 
					d = Math.min(d, dist(band.get(i), band.get(j)));
				else  
					break;
	}

4. ์ฝ”๋“œ

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

public class Divide_2 {
	public static void main(String[] args) throws NumberFormatException, IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
		StringTokenizer st;

		int N = Integer.parseInt(br.readLine());
		ArrayList<Point> arrList = new ArrayList<>();
		for (int i = 0; i < N; i++) {
			st = new StringTokenizer(br.readLine());

			int x = Integer.parseInt(st.nextToken());
			int y = Integer.parseInt(st.nextToken());

			arrList.add(new Point(x, y));
		}
		Collections.sort(arrList, (p1, p2) -> p1.x - p2.x); // x์ขŒํ‘œ ๊ธฐ์ค€์œผ๋กœ ์˜ค๋ฆ„์ฐจ์ˆœ ์ •๋ ฌ.

		bw.write(closestPair(arrList, 0, N - 1) + "\n");
		bw.close();
		br.close();
	}

	public static int dist(Point p, Point q) {
		return (p.x - q.x) * (p.x - q.x) + (p.y - q.y) * (p.y - q.y);
	}

	static int bruteForce(ArrayList<Point> arrList, int start, int end) {
		int minDist = Integer.MAX_VALUE;
		for (int i = start; i < end; i++) {
			for (int j = i + 1; j <= end; j++) {
				int k = dist(arrList.get(i), arrList.get(j));
				minDist = Math.min(k, minDist);
			}
		}

		return minDist;
	}

	public static int closestPair(ArrayList<Point> arrList, int start, int end) {
		int n = end - start + 1;

		if (n <= 3) {
			return bruteForce(arrList, start, end);
		}

		int mid = (start + end) / 2;

		int d = Math.min(closestPair(arrList, start, mid), closestPair(arrList, mid + 1, end));

		
		ArrayList<Point> band = new ArrayList<>();
		for (int i = start; i <= end; i++) {
			int t = arrList.get(mid).x - arrList.get(i).x;

			if (t * t < d) {
				band.add(arrList.get(i));
			}
		}
		
		Collections.sort(band, (p1, p2) -> p1.y - p2.y);

		for (int i = 0; i < band.size() - 1; i++) {
			for (int j = i + 1; j < band.size(); j++) {
				int t = band.get(j).y - band.get(i).y;

				if (t * t < d) 
					d = Math.min(d, dist(band.get(i), band.get(j)));
				else  
					break;
				
			}
		}

		return d;
	}

	static class Point {
		int x;
		int y;

		Point(int x, int y) {
			this.x = x;
			this.y = y;
		}
	}

}

5. ๊ฒฐ๊ณผ


์„ฑ๊ณต~

profile
๐ŸŒฑ์ดˆ๋ณด ๊ฐœ๋ฐœ์ž๐ŸŒฑ

0๊ฐœ์˜ ๋Œ“๊ธ€