Computer >> 컴퓨터 >  >> 프로그램 작성 >> C++

C++에서 정원에 물을 주기 위해 여는 최소 탭 수


x축에 1차원 정원이 있다고 가정합니다. 정원의 시작 위치는 0이고 끝 위치는 n입니다. 정원의 [0, 1, ..., n] 지점에 n + 1개의 탭이 있습니다. 우리가 정수 n과 길이 n + 1의 정수 배열 범위가 있고 여기서 범위[i]는 i번째 수돗물이 될 수 있습니다. [i - 범위[i], i + 범위[i]] 엽니다.

정원 전체에 물을 공급할 수 있는 최소 수도꼭지 수를 찾아야 합니다. 가능한 솔루션이 없으면 -1을 반환합니다.

따라서 입력이 n =5이고 범위 =[3,4,1,1,1,0]인 경우 출력은 1이 됩니다. 두 번째 탭에서와 같이 전체 접지 [-3 5까지].

이 문제를 해결하기 위해 다음 단계를 따릅니다. −

  • 이 문제를 해결하기 위해 다음 단계를 따릅니다. −

  • 크기(n + 1)의 배열 v를 정의하고 -1로 채웁니다.

  • i:=0 초기화의 경우, i <=n일 때 업데이트(i를 1만큼 증가), -

    수행
    • u :=i의 최대값 - 범위[i] 및 0

    • e :=n 및 i + 범위의 최소값[i]

    • v[u] :=v[u] 및 e의 최대값

  • v[0]이 -1과 같으면 -

    • 반환 -1

  • 커 :=v[0]

  • 나는 :=0, 다음 :=0

  • curr

    • 내가 <=curr, 하는 동안 -

      • 다음 :=다음 및 v[i]

        의 최대값
      • (i를 1씩 증가)

    • 다음이 curr과 같으면 -

      • 반환 -1

    • curr :=다음

    • (ret 1 증가)

  • 리턴 렛

이해를 돕기 위해 다음 구현을 살펴보겠습니다. −

예시

#include <bits/stdc++.h>
using namespace std;
class Solution {
   public:
   int minTaps(int n, vector<int>& ranges) {
      int ret = 1;
      vector<int> v(n + 1, -1);
      for (int i = 0; i <= n; i++) {
         int u = max(i - ranges[i], 0);
         int e = min(n, i + ranges[i]);
         v[u] = max(v[u], e);
      }
      if (v[0] == -1)
      return -1;
      int curr = v[0];
      int i = 0;
      int next = 0;
      while (curr < n) {
         while (i <= curr) {
            next = max(next, v[i]);
            i++;
         }
         if (next == curr)
         return -1;
         curr = next;
         ret++;
      }
      return ret;
   }
};
main(){
   Solution ob;
   vector<int> v = {3,4,1,1,1,0};
   cout << (ob.minTaps(5, v));
}

입력

5, {3,4,1,1,1,0}

출력

1