본문 바로가기
알고리즘

[BOJ] 백준 1011번: Fly me to the Alpha Centauri

by 강성주의 알고리즘 2020. 8. 11.

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

 

1011번: Fly me to the Alpha Centauri

우현이는 어린 시절, 지구 외의 다른 행성에서도 인류들이 살아갈 수 있는 미래가 오리라 믿었다. 그리고 그가 지구라는 세상에 발을 내려 놓은 지 23년이 지난 지금, 세계 최연소 ASNA 우주 비행��

www.acmicpc.net

x 지점에서 출발하여 y 지점으로 가는데 이전에 k번 건너뛰었다면 다음번엔 k-1번 k번 k+1 번 건너 뛸 수 있을때 x에서 y로 가는데 최소 점프수를 구하는 문제입니다. 다만 마지막 y 지점에 도착할 땐 반드시 1번 뛰어야 합니다.

만약 내가 x에서 y로 갈때 최소 점프수로 가고 싶다면 점프할때 k를 1씩 늘리거나 유지하다가 어느 시점에서 부터 k를 1씩 감소하시키면서 y에 도착하는 것이 가장 베스트일겁니다.

즉 1 2 3 2 1 과 같은 꼴이 될겁니다. 

1 2 3 2 1 는 1+2, 2+1, 3으로 3의 제곱인 9만큼의 거리에서 최적으로 점프하는 경우입니다.

만약 1 2 3 4 3 2 1 로 점프를 하는 경우는 1+3 , 2+2 , 3+1, 4 로 4의 제곱인 16만큼의 거리에서 최적으로 뛸 수 있습니다.

이로써 우리는 x와 y의 거리가 특정 자연수 n에 대한 제곱인 경우 최적의 점프 횟수가 2*n -1 인것을 알았습니다.

그럼 가야하는 거리가 (n-1)*(n-1) 과 n*n 사이의 거리의 최적의 점프횟수는 어떻게 구할까요

만약 가야하는 거리가 12인 경우를 구해봅시다. sqrt(12)는 3.xx로 3이라고 보면 아마도 9의 최적 횟수 + 1 이상과 16의 최적 점프 횟수 이하의 어느 한 수 일겁니다. 

16인 경우부터 거꾸로 가면서 확인해보겠습니다. 

거리 16 : 1 2 3 4 3 2 1 (6)

거리 15 : 1 2 3 3 3 2 1 (6)

거리 14 : 1 2 3 3 2 2 1 (6)

거리 13 : 1 2 3 3 2 1 1 (6)

거리 12 : 1 2 3 3 2 1  (5)

횟수를 줄이기 위해서 k는 앞 뒤 점프 횟수와 k-1 k k+1 사이를 유지해야하므로 가장 큰 점프 횟수를 줄여야합니다.

즉, 거리가 16인 경우에 최적 점프 횟수를 줄이려면 적어도 sqrt(16) = 4 의 거리가 줄어야 합니다.

#include <iostream>
#include <math.h>
#include <algorithm>
using namespace std;
typedef long long ll;
typedef double d;
typedef pair<d, d> pdd;
typedef pair<int,int> pii;
int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL); cout.tie(NULL);
	int t;
	cin >> t;
	for (; t--;) {
		int x, y ,ans =0;
		cin >> x >> y;
		int n = y - x;
		int r = sqrt(n);
		if(r*r == n){
			ans = r * 2 - 1;
		}
		else {
			ans = 2 * (r + 1) - 1;
			int dif = (r + 1) * (r + 1) - n;
			if (dif >= r + 1) {
				ans -= 1;
			}
		}
		cout << ans <<"\n";
	}
}

 

반응형

'알고리즘' 카테고리의 다른 글

[BOJ] 백준 1026번: 보물  (2) 2020.08.12
[BOJ] 백준 1024번: 수열의 합  (2) 2020.08.12
[BOJ] 백준 1007번: 벡터 매칭  (0) 2020.08.11
[BOJ] 백준 1004번: 어린 왕자  (0) 2020.08.11
[BOJ] 백준 1002번: 터렛  (1) 2020.08.11