1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ABC379Cの自分なりの回答

Posted at

前提

$X_i$と$A_i$をpairで繋げれば良さそう。
$X_i$を基準にソートしなきゃなぁ(でもやり方わからん)

vector< pair < long long, long long>>のソート

#include <vector>
#include <utility>
#include <algorithm>
using namespace std;

vector<pair<long long, long long>> v;

// v[i].firstに$X_i$のデータを入れる

// v[i].secondに$A_i$のデータを入れる

sort(v.begin(), v.end()); //v[i].firstを基準に昇順ソート

石が配れるかどうか調べながら、後で使う情報を集める

この問題は、石を左から右にしか配れない。
かつ、1つのマスに1つしか石を置けない。

これより、石を置く直前を境に配れるかどうか判定を行う。

なぜ、石を置く直前を境に配れるかどうか判定を行えば良いのか。

一般的な考え方として、「変化の起こる前後に着目すると良い」というのがある。

さて、今回の「変化の起こる前後」とはどこだろうか?
今回の「変化の起こる前後」は、$X_i$で石が$A_i$個増えるというイベントである。
$X_i$で石が$A_i$個増えるまで、つまり$X_{i-1}$から$X_i-1$までは石が増えないのである。
この問題では、石は左から右にしか運べないため、$1$~$X_i-1$までに石が$X_i-1$個いなければならないことがわかる。

これをfor文で回して、この条件を満たすか調べれば良い。

石の移動量を求める

これはまず、やったことがないと思いつかないと思う。

まず、具体例を考えてみる。
初期位置と最終位置の全ての石のマスの位置の合計を求める。

マス1に2個、マス3に1個、マス4に3個あった場合、
$S_{pre} = 1 + 1 + 3 + 4 + 4 + 4$

これは最終的にマス1に1個、マス2に1個、...、マス6に1個となるため、
$S_{pos} = 1 + 2 + 3 + 4 + 5 + 6$

これより、それぞれのマスがどのくらい移動したのかは、
$S_{dif} = 0 + 1 + 0 + 0 + 1 + 2$
として表せる!
これより、石の移動した時の和は
$S_{dif} = S_{pos} - S_{pre}$ で表せば良いじゃないか!!とわかる。

思いつくかこんなもん。

感想

「変化の起こる前後に着目すると良い」という考え方は早めに身につけていきたい。
この問題だけではまだ身についたとは言えないと思うので、色々な問題をどんどん解いていきたい。

移動量は思いつかん。(n回目)
こればかりは経験なのでは...?

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?