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?

AtCoderにてひどいコードを書いてしまった自分への戒め

Posted at

ABC414 C

今回の問題:https://atcoder.jp/contests/abc414/tasks/abc414_c

問題

問題の内容は$A$と$N$が与えられるから10進数とA進数で回文(左右対称)になっている$N$以下の数字の総和を出力せよというもの

制約

$1≤A≤9$
$1≤N≤10^{12}$

条件的に$O(N)$は無理だとわかるので$N$以下の数値をすべて試していたらTLEになる

方向性

問題の制約の範囲内で回文になっている10進数をすべて配列に入れてそれをすべて確かめる
ループの最大値的に10進数の回文を作るオーダーが基準になりそう
メモはこんな感じ
image.png
こんなかんじで続けると12桁時点での数もまあ収まりそう
解説によるオーダーは$O(\sqrt{N}logN)$らしい

それでできてしまったのがこれ
※マクロは省略してあります

void ntom(const string str, const int n, const int m, string &res)
{
    unsigned long sum = 0;
    for (char c : str)
    {
        sum = sum * n + (c - '0');
    }
    res = "";
    do
    {
        int num = sum % m;
        res = static_cast<char>(num + '0') + res;
        sum /= m;
    } while (sum);
}

int main()
{
    ll A, N;
    cin >> A >> N;
    ull ans = 0;
    vector<string> v;
    // 1
    rep(i, 1, 10)
    {
        v.push_back(to_string(i));
    }
    // 2
    rep(i, 1, 10)
    {
        v.push_back(to_string(i * 10 + i));
    }
    // 3
    rep(i, 1, 10)
    {
        rep(j, 0, 10)
        {
            v.push_back(to_string(i * 100 + j * 10 + i));
        }
    }
    // 4
    rep(i, 1, 10)
    {
        rep(j, 0, 10)
        {
            v.push_back(to_string(i * 1000 + j * 100 + j * 10 + i));
        }
    }
    // 5
    rep(i, 1, 10)
    {
        rep(j, 0, 10)
        {
            rep(k, 0, 10)
            {
                v.push_back(to_string(i * 10000 + j * 1000 + k * 100 + j * 10 + i));
            }
        }
    }
    // 6
    rep(i, 1, 10)
    {
        rep(j, 0, 10)
        {
            rep(k, 0, 10)
            {
                v.push_back(to_string(i * 100000 + j * 10000 + k * 1000 + k * 100 + j * 10 + i));
            }
        }
    }

    // 7
    rep(i, 1, 10)
    {
        rep(j, 0, 10)
        {
            rep(k, 0, 10)
            {
                rep(l, 0, 10)
                {
                    v.push_back(to_string(i * 1000000 + j * 100000 + k * 10000 + l * 1000 + k * 100 + j * 10 + i));
                }
            }
        }
    }
    // 8
    rep(i, 1, 10)
    {
        rep(j, 0, 10)
        {
            rep(k, 0, 10)
            {
                rep(l, 0, 10)
                {
                    v.push_back(to_string(i * 10000000 + j * 1000000 + k * 100000 + l * 10000 + l * 1000 + k * 100 + j * 10 + i));
                }
            }
        }
    }
    // 9
    rep(i, 1, 10)
    {
        rep(j, 0, 10)
        {
            rep(k, 0, 10)
            {
                rep(l, 0, 10)
                {
                    rep(m, 0, 10)
                    {
                        v.push_back(to_string(i * 100000000 + j * 10000000 + k * 1000000 + l * 100000 + m * 10000 + l * 1000 + k * 100 + j * 10 + i));
                    }
                }
            }
        }
    }

    // 10
    rep(i, 1, 10)
    {
        rep(j, 0, 10)
        {
            rep(k, 0, 10)
            {
                rep(l, 0, 10)
                {
                    rep(m, 0, 10)
                    {
                        v.push_back(to_string(i * 1000000000 + j * 100000000 + k * 10000000 + l * 1000000 + m * 100000 + m * 10000 + l * 1000 + k * 100 + j * 10 + i));
                    }
                }
            }
        }
    }

    // 11
    rep(i, 1, 10)
    {
        rep(j, 0, 10)
        {
            rep(k, 0, 10)
            {
                rep(l, 0, 10)
                {
                    rep(m, 0, 10)
                    {
                        rep(n, 0, 10)
                        {
                            v.push_back(to_string(i * 10000000000 + j * 1000000000 + k * 100000000 + l * 10000000 + m * 1000000 + n * 100000 + m * 10000 + l * 1000 + k * 100 + j * 10 + i));
                        }
                    }
                }
            }
        }
    }

    // 12
    rep(i, 1, 10)
    {
        rep(j, 0, 10)
        {
            rep(k, 0, 10)
            {
                rep(l, 0, 10)
                {
                    rep(m, 0, 10)
                    {
                        rep(n, 0, 10)
                        {
                            v.push_back(to_string(i * 100000000000 + j * 10000000000 + k * 1000000000 + l * 100000000 + m * 10000000 + n * 1000000 + n * 100000 + m * 10000 + l * 1000 + k * 100 + j * 10 + i));
                        }
                    }
                }
            }
        }
    }

    for (string x : v)
    {
        if (stoull(x) > N)
            break;
        string k;
        ntom(x, 10, A, k);
        if (k == string(k.rbegin(), k.rend()))
        {
            ans += stoull(x);
        }
    }

    cout << ans << el;
}

こんなコードですがACになってしまいます/(^o^)\ナンテコッタイ

10進数の数値をA進数の数値の文字列にする関数はこちらhttps://qiita.com/hanpeno/items/4fa5fbea04c2db1ae722 を使わせていただきました 感謝感謝

回文かの確認も最初はfor文で回していたのですがググっていたらstringのコピーインストラクタを使えば行けるという記事https://www.delftstack.com/ja/howto/cpp/cpp-palindrome/ を見かけたので採用

正直再帰とか使えば実装できる気がするが考えるより12回コピペしたほうが早いと思ったのでこんな結果に

競技プログラミングだからいいけど共同作業とかする時はもっと見やすいコードを書けという自分への戒め

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?