[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();
}
}