[BOJ] 15889 - 호 안에 수류탄이야!!

Sierra·2022년 2월 11일
0

[BOJ] Greedy

목록 보기
16/33
post-thumbnail

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

문제

“호 안에 수류탄!!”

대한건아 욱제는 수류탄 투척 훈련을 받고 있다. 욱제를 필두로, 훈련장에는 욱제를 포함한 N명의 전우들이 일렬(1열 횡대 ㅎ)로 서있다. 군대에 끌려온 사실에 심술이 난 욱제는 수류탄의 안전핀을 뽑아 전우에게 던졌다. 마찬가지로 심술이 난 전우들도 욱제가 던진 수류탄을 받아 전우들에게 던지기 시작했다.

이제 수류탄은 뜨거운 감자처럼 욱제와 전우들 사이를 옮겨 다닌다. 전우들은 팔 힘이 모두 다르기 때문에 수류탄을 던질 수 있는 사거리도 모두 다르다. 욱제와 전우들이 가지고 노는 훈련용 수류탄은 바닥에 떨어지기 전에는 절대 터지지 않는 특수한 수류탄이다.

욱제와 전우들은 특급 전사이기 때문에 사거리 내에 있는 누구에게나 정확히 수류탄을 던질 수 있고, 마찬가지로 정확히 날아오는 수류탄은 항상 받을 수 있다. 한 위치에 여러명의 전우가 서있다면 그 중 아무나 받아 다음 전우에게 던질 수 있다.

누군가의 팔 힘이 모자라 수류탄이 다음 전우에게 전달되지 못하고 바닥에 떨어지는 경우도 있을 수 있다. 이때는 수류탄에서 폭죽이 터지며 불꽃놀이가 시작되고, 동시에 욱제와 전우들의 영창 생활도 시작된다.

???: “중대장은 오늘 너희에게 큰 실망을 했다”

이 게임을 중대장님이 모르게 끝마치려면 마지막 전우(왼쪽에서부터 N번째 전우)가 수류탄을 받아 조용히 행사용 폭죽 더미에 섞어놓아야 한다. 욱제와 전우들은 항상 최선을 다해 최적의 방법으로 게임을 조용히 끝마칠 수 있도록 노력한다. 과연 영창을 건 이 게임의 끝은 어디일까?

입력

첫째 줄에 욱제를 포함한 전우들의 인원 수 N이 주어진다. (1 ≤ N ≤ 30,000)

둘째 줄에 욱제를 포함한 N명 전우들의 좌표가 주어진다. 이는 수직선 위의 음이 아닌 정수로 표현되어 주어지며 욱제의 좌표는 항상 0이다. (0 ≤ 좌표 ≤ 1,000,000)

N이 1보다 크다면, 셋째 줄에 욱제를 포함하고 마지막 전우를 제외한 N-1명 전우들의 사거리가 욱제부터 순서대로 주어진다. N이 1이면 셋째 줄이 주어지지 않는다. (0 ≤ 사거리 ≤ 1,000,000)

출력

게임이 조용히 마무리 될 수 있으면 “권병장님, 중대장님이 찾으십니다”를, 그렇지 않으면 “엄마 나 전역 늦어질 것 같아”을 출력한다.

예제 입출력

  • 예제 입력 1
5
0 5 10 15 100
10 5 6 100
  • 예제 출력 1
권병장님, 중대장님이 찾으십니다
  • 예제 입력 2
5
0 5 10 15 100
10 5 6 0
  • 예제 출력 2
엄마 나 전역 늦어질 것 같아

Solution

진짜 제대로 고문관들이다. 영창으로 끝나면 다행인줄 알아라...

#include <iostream>
#include <vector>
using namespace std;

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    int N;
    cin >> N;
    vector<int> pointList(N);
    for(int i = 0; i < N; i++) cin >> pointList[i];
    if(N != 1){
        vector<int> rangeList(N-1);
        for(int i = 0; i < N-1; i++) cin >> rangeList[i];
        int maxRange = 0;
        for(int i = 0; i < N-1; i++){
            maxRange = max(maxRange, pointList[i] + rangeList[i]);
            if(maxRange >= pointList[i+1]) continue;
            else{
                cout << "엄마 나 전역 늦어질 것 같아\n";
                return 0;
            }
        }
    }
    cout << "권병장님, 중대장님이 찾으십니다\n";
    return 0;
}

최적의 경로를 구할 필요는 없다. 하나 확실한 건 당장 본인이 앞에있는 사람한테까지 전달을 할 수는 있는지 확인해야 한다는 것이다.

자신보다 앞에, 더 앞에 있는 사람에게 전달 할 수도 있다. 그러므로 기준으로 본인의 사정거리 + 본인의 인덱스 값의 최댓값을 계속 maxRange 변수에 저장해둔다.

만약 i에 있는 놈이 사정거리가 짧아서(입대는 어떻게 한거야...) 당장 앞에있는 놈한테도 줄 수 없다 치자. 그런데 뒤에 있는 놈의 사정거리가 길어서 i의 앞에 있는 놈에게 보낼 수 있다면? 그러면 전달 가능한 것이다. 그래서 maxRange 변수에 매 탐색마다 최대 범위를 갱신하는 것이다.

이런 문제는 최적의 경우를 구하는 문제가 아니므로 어렵게 생각해선 안된다. 일단 보낼 수 있느냐? 가 중요했던 문제.

profile
블로그 이전합니다 : https://swj-techblog.vercel.app/

0개의 댓글