はまやんはまやんはまやん

hamayanhamayan's blog

E869120 and Lucky Numbers [yukicoder No.653]

https://yukicoder.me/problems/no/653

解法

https://yukicoder.me/submissions/238509

桁DPかなと言う感じだが、下から貪欲に特定していけばいい。
基本的な方針としては以下の通りである

  • 足して2なら6+6しかなくて、1つ繰り上げ
  • 足して3なら6+7しかなくて、1つ繰り上げ
  • 足して4なら7+7しかなくて、1つ繰り上げ
  • 足して6なら片方は数が無く(桁数が足りない)、片方は6
  • 足して7なら片方は数が無く(桁数が足りない)、片方は7
  • それ以外は無理

つまり、下の桁から2つのラッキーナンバーを決定的に確定できる。
足して6,7を1回やってしまうと、片方は数が無くなる必要があるため、それ以降に2,3,4が来るのはダメ。
足して6,7が1の位で起こるのは、片方のラッキーナンバーが0となってしまうので、ダメ。
最上位桁が繰り上げだけで1となる場合もコーナーとなりうるので、これも注意して実装する。

string P;
//---------------------------------------------------------------------------------------------------
#define yes "Yes"
#define no "No"
string solve() {
    int n = P.length();

    int pre = 0, flag = 0;
    rrep(i, n - 1, 0) {
        int c = P[i] - '0' - pre;

        if (2 <= c and c <= 4) {
            if (flag == 1) return no;
            pre = 1;
        } else if (6 <= c and c <= 7) {
            if (i == n - 1) return no;
            flag = 1;
            pre = 0;
        }
        else if (c == 0 and i == 0) return yes;
        else return no;
    }

    if(pre == 0) return yes;
    return no;
}
//---------------------------------------------------------------------------------------------------
void _main() {
    cin >> P;
    cout << solve() << endl;
}