SRM 597

1184->1214(Blue)
SRM 597 (div2), ox-, +50/-0, 264.1pts, 174th

Div.1に戻りました。

Easy
for all elem = a {
amin = minelem(a), there exists m in N elem / amin = 2^m
}
を判定する。
どうでもいいけど、given nに対して、there exists m in N n=2^mの判定方法として、(n & n – 1)がある。

Med
result -1はソートして同一かチェック。
result m ⇔ B[m:end]がAの部分列
これだけで良いのだが、下の部分列として存在の実装をミスった。馬鹿です。部分問題に加えます。
ミスった原因。
-forやwhileがこんがらがる問題は、きちんと紙で構造を確かめなければならない。
-終端条件から考えると楽
-条件が網羅的であることを確認しなければならない
-終端条件が更新条件によって変わる場合がある。下の解法2参照。
-whileとbreak, continueの構造は極めてミスりやすいので、他の関数を作ったほうが良いと思われる。インクリメントの変数の取り扱いが面倒。

部分問題、string A, Bについて、AがBを部分列として持つかを判定せよ。
解法0:
B[i]がA[j:end]に存在するかを逐一チェック。
終端条件
i: last && A[j:end]にB[i]がある→true
i: last && A[j:end]にB[i]がない→false
i: not last && A[j:end]にB[i]がない→false
更新条件
i: not last && A[j:end]にB[i]がある→jをfind(A[j:end], B[i]) + 1に設定

解法1:
B[i]がA[j:end]に存在するかを逐一チェック。
終端条件
j: done →false
更新条件
j: not done && A[j] == B[i]→j++, break
j: not done && A[j] != B[i]→j++

解法2:
whileとforの混成は面倒なので、while(1)でi, jを自分で管理する。
終端条件
i: not done && j: done→false
i: done && j: not done→true
i: done && j: done→???
更新条件
i: not done && j: not done && A[j] == B[i]→i++, j++
i: not done && j: not done && A[j] != B[i]→j++
???は、更新条件1行目によって更新された時にのみ発生。これは???=doneとして扱うべき。

bool ans0(string A, string B)
{
    int j = 0;
    for (int i = 0; i < B.length(); i++, j++) {
        int tmpj = A.substr(j, A.length() - j).find(B[i]);
        if (tmpj == string::npos) {
            return false;
        } else if (i != B.length() - 1) {
            j += tmpj;
        } else {
            return true;
        }
    }
    return true;
}


bool ans1(string A, string B)
{
    int j = 0;
    for (int i = 0; i < B.length(); i++) {
        while (1) {
            if (A[j++] == B[i])
                break;
            if (j >= A.length())
                return false;
        }
    }
    return true;
}

bool ans2(string A, string B)
{
    int i = 0, j = 0;
    while (1) {
        if (i >= B.length())
            return true;
        else if (j >= A.length())
            return false;
        else if (A[j] != B[i])
            j++;
        else {
            i++, j++;
        }
    }
}

Hard
わけがわからないよ。
勉強します。

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>