結果

問題 No.2287 ++ -- *=a /=a
ユーザー みここみここ
提出日時 2023-04-22 18:17:36
言語 C++17
(gcc 12.3.0 + boost 1.83.0)
結果
AC  
実行時間 834 ms / 2,000 ms
コード長 4,130 bytes
コンパイル時間 1,399 ms
コンパイル使用メモリ 106,804 KB
実行使用メモリ 5,376 KB
最終ジャッジ日時 2024-04-28 22:28:22
合計ジャッジ時間 7,308 ms
ジャッジサーバーID
(参考情報)
judge4 / judge1
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
5,248 KB
testcase_01 AC 3 ms
5,376 KB
testcase_02 AC 3 ms
5,376 KB
testcase_03 AC 3 ms
5,376 KB
testcase_04 AC 2 ms
5,376 KB
testcase_05 AC 3 ms
5,376 KB
testcase_06 AC 147 ms
5,376 KB
testcase_07 AC 150 ms
5,376 KB
testcase_08 AC 150 ms
5,376 KB
testcase_09 AC 90 ms
5,376 KB
testcase_10 AC 66 ms
5,376 KB
testcase_11 AC 58 ms
5,376 KB
testcase_12 AC 54 ms
5,376 KB
testcase_13 AC 53 ms
5,376 KB
testcase_14 AC 52 ms
5,376 KB
testcase_15 AC 51 ms
5,376 KB
testcase_16 AC 48 ms
5,376 KB
testcase_17 AC 47 ms
5,376 KB
testcase_18 AC 696 ms
5,376 KB
testcase_19 AC 438 ms
5,376 KB
testcase_20 AC 366 ms
5,376 KB
testcase_21 AC 318 ms
5,376 KB
testcase_22 AC 286 ms
5,376 KB
testcase_23 AC 266 ms
5,376 KB
testcase_24 AC 251 ms
5,376 KB
testcase_25 AC 241 ms
5,376 KB
testcase_26 AC 232 ms
5,376 KB
testcase_27 AC 834 ms
5,376 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <iostream>
#include <cassert>
#include <queue>
#include <map>
using namespace std;
typedef long long ll;

template <typename T = int>
struct Graph
{
public:
    using value_type = T;

    struct Edge
    {
        int from, to;
        T cost;
        int id;

        operator int() const
        {
            return to;
        }
    };

    Graph() {}

    Graph(int n) : n(n), m(0), g(n) {}

    void add_directed_edge(int from, int to, T cost = 1)
    {
        assert(0 <= from && from < n);
        assert(0 <= to && to < n);
        g[from].push_back((Edge){from, to, cost, m++});
    }

    void add_undirected_edge(int from, int to, T cost = 1)
    {
        assert(0 <= from && from < n);
        assert(0 <= to && to < n);
        g[from].push_back((Edge){from, to, cost, m});
        g[to].push_back((Edge){to, from, cost, m++});
    }

    int size()
    {
        return n;
    }

    int edge_size()
    {
        return m;
    }

    inline const std::vector<Edge> &operator[](const int &u) const
    {
        return g[u];
    }

    inline std::vector<Edge> &operator[](const int &u)
    {
        return g[u];
    }

private:
    int n, m;
    std::vector<std::vector<Edge>> g;
};

template <typename GRAPH>
std::vector<typename GRAPH::value_type> dijkstra(GRAPH &g, int s)
{
    using T = typename GRAPH::value_type;
    using P = std::pair<T, int>;
    int n = g.size();
    assert(s >= 0 && s < n);
    std::vector<T> d(n, -1);
    std::priority_queue<P, std::vector<P>, std::greater<P>> que;
    d[s] = 0;
    que.push(P(0, s));
    while (que.size())
    {
        auto [dist, u] = que.top();
        que.pop();
        if (d[u] < dist)
        {
            continue;
        }
        for (auto e : g[u])
        {
            int v = e.to;
            if (d[v] == -1 || d[v] > d[u] + e.cost)
            {
                d[v] = d[u] + e.cost;
                que.push(P(d[v], v));
            }
        }
    }
    return d;
}

int main()
{
    int t;
    cin >> t;
    while (t--)
    {
        ll x, y, a;
        cin >> x >> y >> a;
        ll z = y;
        ll p = x, q = y;
        Graph<ll> g(200);
        map<ll, int> mp;
        int r[200];
        int k = 0;
        if (!mp.count(x))
        {
            r[k] = x;
            mp[x] = k++;
        }
        if (!mp.count(y))
        {
            r[k] = y;
            mp[y] = k++;
        }
        if (!mp.count(y + 1))
        {
            r[k] = y + 1;
            mp[y + 1] = k++;
        }
        while (x || y)
        {
            if (x <= y)
            {
                g.add_directed_edge(mp[x], mp[y], y - x);
                y /= a;
                if (!mp.count(y))
                {
                    r[k] = y;
                    mp[y] = k++;
                }
                if (!mp.count(y + 1))
                {
                    r[k] = y + 1;
                    mp[y + 1] = k++;
                }
            }
            else
            {
                g.add_directed_edge(mp[x], mp[y + 1], x - (y + 1));
                if (!mp.count(x / a))
                {
                    r[k] = x / a;
                    mp[x / a] = k++;
                }
                g.add_directed_edge(mp[x], mp[x / a], 1);
                x /= a;
            }
        }
        while (true)
        {
            ll w = z / a;
            g.add_directed_edge(mp[z], mp[z + 1], 1);
            g.add_directed_edge(mp[z + 1], mp[z], 1);
            g.add_directed_edge(mp[w], mp[z], z - w * a + 1);
            g.add_directed_edge(mp[w + 1], mp[z + 1], (w + 1) * a - (z + 1) + 1);
            if (z >= w + a)
            {
                g.add_directed_edge(mp[z], mp[w + 1], z - (w + 1));
                g.add_directed_edge(mp[w + 1], mp[z], z - (w + 1));
            }
            if (z >= (w / a + 1) * a)
            {
                g.add_directed_edge(mp[w / a + 1], mp[z], z - (w / a + 1) * a + 1);
            }
            if (!z)
            {
                break;
            }
            z = w;
        }
        vector<ll> d = dijkstra(g, mp[p]);
        cout << d[mp[q]] << endl;
    }
}
0