C ++
 Computer >> コンピューター >  >> プログラミング >> C ++

すべてのモンスターを殺すために爆弾を配置するための最小数の場所を見つけるためのC++プログラム


2つの配列XとHがあるとします。どちらもN個の要素を持ち、さらに2つの数字DとAがあります。物語の中で、銀狐がN個のモンスターと戦っているとします。モンスターは一列に並んでおり、i番目のモンスターの座標はX [i]、体力はH[i]です。シルバーフォックスは爆弾を使ってモンスターを攻撃することができます。場所xに爆弾を落とすと、x-Dからx + Dの範囲内のすべてのモンスターにダメージを与えます。それらの体力はAだけ減少します。すべてのモンスターの体力が0になると、キツネが勝ちます。勝つために必要な最小限のものを見つける必要があります。

したがって、入力がD=3のような場合。 A =2; X =[1、5、9]; H =[2、4、2]の場合、出力は2になります。これは、最初に座標4で爆弾が発生し、新しいヘルス値が[0、2、2]になり、次に位置6ですべてのヘルス値が[0、0、 0]。

ステップ

これを解決するには、次の手順に従います-

Define a large array q
Define an array of x and h pairs
n := size of X
d := D
a := A
for initialize i := 1, when i <= n, update (increase i by 1), do:
   num[i].x := X[i - 1]
   num[i].h := H[i - 1]
sort the array num
sum := 0
for initialize i := 1, when i <= n, update (increase i by 1), do:
   q[i] := q[i] + q[i - 1]
   num[i].h := num[i].h - q[i] * a
   if num[i].h <= 0, then:
      Ignore following part, skip to the next iteration
   p := (if num[i].h mod a is same as 0, then num[i].h / a, otherwise num[i].h / a + 1)
   tmp := num[i].x + 2 * d
   sum := sum + p
   q[i] := q[i] + p
   l := i, r = n
   while l < r, do:
      mid := (l + r + 1) / 2
      if num[mid].x <= tmp, then:
         l := mid
      Otherwise
         r := mid - 1
      q[l + 1] - = p
return sum

理解を深めるために、次の実装を見てみましょう-

#include <bits/stdc++.h>
using namespace std;

const int maxn = 2e5 + 20;
int n;
int d, a, q[maxn];
struct node{
   int x, h;
   bool operator<(const node& a) const{
      return x < a.x;
   }
} num[maxn];
int solve(int D, int A, vector<int> X, vector<int> H){
   n = X.size();
   d = D;
   a = A;
   for (int i = 1; i <= n; i++){
      num[i].x = X[i - 1];
      num[i].h = H[i - 1];
   }
   sort(num + 1, num + n + 1);
   int sum = 0;
   for (int i = 1; i <= n; i++){
      q[i] += q[i - 1];
      num[i].h -= q[i] * a;
      if (num[i].h <= 0)
         continue;
      int p = (num[i].h % a == 0 ? num[i].h / a : num[i].h / a + 1);
      int tmp = num[i].x + 2 * d;
      sum += p;
      q[i] += p;
      int l = i, r = n;
      while (l < r){
         int mid = (l + r + 1) >> 1;
         if (num[mid].x <= tmp)
            l = mid;
         else
            r = mid - 1;
      }
      q[l + 1] -= p;
   }
   return sum;
}
int main(){
   int D = 3;
   int A = 2;
   vector<int> X = { 1, 5, 9 };
   vector<int> H = { 2, 4, 2 };
   cout << solve(D, A, X, H) << endl;
}

入力

3, 2, { 1, 5, 9 }, { 2, 4, 2 }

出力

2

  1. C++で対戦相手を捕まえるために必要な最小ステップ数を見つけるためのプログラム

    [u、v]の形式のツリーエッジのリストがあると仮定します。これは、uとvの間に無向エッジがあることを示します。また、xとyの2つの値があります。ノードxにいて、対戦相手がノードyにいる場合。最初のラウンドでは移動し、次のラウンドでは対戦相手が移動します。対戦相手は、ラウンドで移動しないことを選択できます。対戦相手を捕まえるのに必要な最小ラウンド数を見つける必要があります。 したがって、入力がedges =[[0、1]、[0、2]、[1、3]、[1、4]]、x =0、y =3のような場合、出力は3になります。最初と同じように、ノード0から1に移動します。その後、対戦相手は現在のノード3に留まり

  2. C ++で75%を維持するために出席する講義の最小数を見つけるためのプログラム

    この問題では、現在のデータまでに開催されたクラスの総数と、学生が参加したクラスの数をそれぞれ表す2つの数字MとNが与えられます。私たちの仕事は、C ++で75%を維持するために、出席する講義の最小数を見つけるプログラムを作成することです。 問題の説明 これは、75%の出席率を維持するための大学生の最大の懸念事項の1つです。このプログラムは、75%の出席を得るために、学生が定期的に出席する講義の最小数を計算します。 問題を理解するために例を見てみましょう 例1 入力 :M =32、N =20 出力 :16 説明 75%以上の出席を達成するには、学生は少なくとも16回の講義に出席す