BackJoon 1011, Fly me to the alpha centauri, 규칙 찾기 문제
오랜만에 글을 올리게 되네요.
https://www.acmicpc.net/problem/1011
위 링크에서 문제 확인 가능합니다.
이 문제는 최소로 공간이동 장치를 사용해서 이동할 수 있는데, 마지막에는 꼭 1로 이동을 해야한다는 조건이 있어서 조금 까다롭습니다.
즉, 보면 다음과 같이 이동이 가능합니다.
1
11 = 2
121 = 4
1221 = 6
1211 = 7
12321 = 9
123321
123221 ....
이런 식인데 대충 알아 냈겠지만 규칙이 존재합니다.
바로 자리수를 기준으로 나누는 겁니다. 2자리의 경우 11이 최대이고
3자리의 경우 121, 4자리는 1221, 5자리는 12321 ... 쭉 생깁니다.
예를 들어 이동하려는 거리가 7 이면 7보다 작거나 같은 곳의 인덱스를 찾으면 됩니다.
바이너리 서치를 통하면 더욱 빠르게 접근할 수 있습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | import java.io.*; import java.util.Arrays; public class B1011 { static int T, x, y, ans, e; static long[] md = new long[100000]; static long pos; static String in; public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out)); T = Integer.parseInt(br.readLine()); initMobileDevice(); for (int i = 0; i < T; i++) { in = br.readLine(); x = Integer.parseInt(in.split(" ")[0]); y = Integer.parseInt(in.split(" ")[1]); pos = 0;e = y - x; ans = Arrays.binarySearch(md, e); if (ans < 0) { ans = Math.abs(ans) - 1; } bw.write(ans + "\n"); bw.flush(); } bw.close(); } public static void initMobileDevice() { md[1] = 1; for (int i = 2; i < 100000; i++) { md[i] = ((long)i / 2) * (((long)i / 2) + 1); md[i] += (i % 2 == 0) ? 0 : (i / 2) + 1; } } } |