[CF1301D] Time to Run

[CF1301D] Time to Run - 构造

Description

给定 $n imes m $ 网格,相连格子之间有双向边,问能否在不经过重复边的情况下,从左上角出发,遍历 (k) 条边

Solution

由于是欧拉图所以一定能走完,关键是去构造一种走法

比如对一个 4 × 4 的网格,我们可以这样走

(1,1) -> (1,4) -> (4,4) -> (1,4) -> (1,3) -> (4,3) -> (1,3) -> (1,2) -> (4,2) -> (1,2) -> (1,1) -> (2,1) -> (2,4) -> (2,1) -> (3,1) -> (3,4) -> (3,1) -> (4,1) -> (4,4) -> (4,1) -> (1,1)
#include <bits/stdc++.h>
using namespace std;

#define int long long

const int N = 1000005;

vector<pair<int, char>> seq;
int n, m;
int k; // 次数限制

// 进行输出

void print()
{
    vector<pair<int, char>> vec;
    for (auto [cnt, ch] : seq)
    {
        int step = min(cnt, k);
        if (step == 0)
            continue;
        k -= step;
        vec.push_back({step, ch});
        if (k == 0)
            break;
    }
    cout << "YES" << endl;
    cout << vec.size() << endl;
    for (auto [x, y] : vec)
        cout << x << " " << y << endl;
}

// 生成序列

void generate()
{
    seq.push_back({m - 1, 'R'});
    for (int i = 1; i < m; i++)
    {
        seq.push_back({n - 1, 'D'});
        seq.push_back({n - 1, 'U'});
        seq.push_back({1, 'L'});
    }
    for (int i = 1; i < n; i++)
    {
        seq.push_back({1, 'D'});
        seq.push_back({m - 1, 'R'});
        seq.push_back({m - 1, 'L'});
    }
    seq.push_back({n - 1, 'U'});
}

// 主程序中需要特判

signed main()
{
    cin >> n >> m >> k;
    if (k > 2 * (2 * n * m - n - m))
    {
        cout << "NO" << endl;
    }
    else
    {
        generate();
        print();
    }
}
原文地址:https://www.cnblogs.com/mollnn/p/14612729.html