題解:CF1301D Time to Run

Ryan_Adam發表於2024-08-02

CF1301D Time to Run 題解

思維題。

分析

把一個格子視作一個點,每個點的度數都是偶數,所以這是一張尤拉圖。而需要走遍整個方格圖,可以證明只要 \(k\) 不超過 \(4nm-2n-2m\) 就一定有解。

很明視訊記憶體在很多種方案,這裡我用的方案是:從左上角出發,向右走 \(m-1\) 步到頭,再向左走 \(m-1\) 步回來,向下走一步。重複以上步驟,直到走到左下角。然後向右走一步,向上走 \(n-1\) 步到頭,向下走 \(n-1\) 步回來。重複上面步驟,直到走到右下角。這時候你會發現你已經走完了這張網格圖裡的所有邊。注意在走的過程中如果步數用完了中斷輸出答案即可。

程式碼

#include <bits/stdc++.h>
using namespace std;
namespace Raiden
{
    int const N = 3005;
    int n, m, k, num[N], cnt;
    char ans[N][5];
    signed work()
    {
        cin >> n >> m >> k;
        if (k > 4 * n * m - 2 * n - 2 * m)return cout << "NO" << endl, 0;
        int anss = 0, sum = k;
        cout << "YES" << endl;
        while (k)
        {
            int _min;
            if (sum - k < m - 1)
            {
                _min = min(k, m - 1);
                num[++cnt] = _min;
                ans[cnt][0] = 'R';
            }
            else if (sum - k < 2 * (m - 1))
            {
                _min = min(k, m - 1);
                num[++cnt] = _min;
                ans[cnt][0] = 'L';
            }
            else if (sum - k < 2 * (m - 1) + 1)
            {
                _min = 1;
                num[++cnt] = _min;
                ans[cnt][0] = 'D';
            }
            else if (sum - k >= 4 * n * m - 2 * n - 2 * m - (n - 1))
            {
                cnt++;
                _min = min(k, n - 1);
                num[cnt] = _min;
                ans[cnt][0] = 'U';
            }
            else if (anss % 3 == 0)
            {
                _min = min(k, m - 1);
                if (_min)
                {
                    cnt++;
                    num[cnt] = _min;
                    ans[cnt][0] = 'R';
                }
                anss++;
            }
            else if (anss % 3 == 1)
            {
                _min = min(k, 3 * (m - 1));
                int __min = _min / 3;
                if (__min)
                {
                    cnt++;
                    num[cnt] = __min;
                    ans[cnt][0] = 'U';
                    ans[cnt][1] = 'D';
                    ans[cnt][2] = 'L';
                }
                if (_min % 3 == 1)
                {
                    num[++cnt] = 1;
                    ans[cnt][0] = 'U';
                }
                if (_min % 3 == 2)
                {
                    num[++cnt] = 1;
                    ans[cnt][0] = 'U';
                    ans[cnt][1] = 'D';
                }
                anss++;
            }
            else
            {
                _min = 1;
                num[++cnt] = _min;
                ans[cnt][0] = 'D';
                anss++;
            }
            k -= _min;
        }
        cout << cnt << endl;
        for (int i = 1; i <= cnt; i++)cout<< num[i] << " " << ans[i] << endl;
        return 0;
    }
}
signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    return Raiden::work();
}

相關文章