h_nosonの日記

競プロ、CTFなど

yukicoder No.365 ジェンガソート

問題
No.365 ジェンガソート - yukicoder
1,2,...,Nの数字がランダムに並べられている.
1回の操作で数字を1つ選んで一番前に持ってくることができる.
数字を昇順に並び替えるための最小の操作の回数はいくつか.

解法
最悪でもN回の操作でソートが可能である.
そこから移動させる必要のない数字を多く見つける事になる.
まず,Nはその後ろにある数字に対して操作を行えばN自体を移動させずにすむ.
もし,N-1Nの前にあるならばNN-1の間の数字を移動させればよくなる.
これを繰り返せば答えが出る.
すなわち,後ろから見ていきN,N-1,N-2,...と並んでいる(間に数字が入ってもいい)最大の数を求め,Nから引いたものが答えである.

ソースコード

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

#define RREP(i,s,e) for (i = s; i >= e; i--)
#define rrep(i,n) RREP(i,n-1,0)
#define REP(i,s,e) for (i = s; i < e; i++)
#define rep(i,n) REP(i,0,n)
#define INF 100000000

typedef long long ll;

int main() {
    int i, n, mx, cnt;
    int a[100000];
    cin >> n;
    rep (i,n) cin >> a[i];
    mx = n;
    cnt = 0;
    rrep (i,n) {
        if (a[i] == mx) {
            cnt++;
            mx--;
        }
    }
    cout << n-cnt << endl;
    return 0;
}