完全に言われた通りに実装してしまうと、 の計算量となって TLE してしまうので、工夫しよう!
問題概要
空の配列に対して、以下の操作を 回行う。
回目の操作では
- 配列の末尾に値
を挿入する
- 配列全体を reverse する
を行う。 回操作後の配列の要素を順に出力せよ。
制約
考えたこと
配列全体を reverse するのには、 の計算量を要するので、それを
回やるのでは全体で
の計算量を要してしまう。
そこで、「reverse 操作は最後にまとめてやる」ことにしよう。実は、操作を言い換えて、次のようにしても一緒なのだ!!!
に対して
が偶数のときは:
を配列の末尾に挿入する
が奇数のときは:
を配列の先頭に挿入する
最後に、 が奇数の場合には、配列全体を reverse する
もしピンと来ない方は、 の場合を実際に手を動かしてみると納得できると思う。
このように「配列全体に対する処理(今回は reverse)を、後でまとめて全部やることにする」というテクニックは頻出だ。
この方法ならば、 の計算量で実現できる。
コード
#include <bits/stdc++.h> using namespace std; int main() { int N, a; cin >> N; deque<int> deq; for (int i = 0; i < N; i++) { cin >> a; if (i % 2 == 0) deq.push_back(a); else deq.push_front(a); } if (N % 2 == 1) reverse(deq.begin(), deq.end()); // 出力 for (int i = 0; i < N; i++) cout << deq[i] << " "; cout << endl; }