The 21st Hunan Provincial Collegiate Programming Contest——2025-湖南省赛-D. Box(不难注意到,只有在 3*3 的网格上,对角线操作才可以减少操作数量) · znzryb
## 题目大意
**题目描述**
给定一个 $n \times m$ 的初始为空的网格,你可以进行以下两种操作:
1. 选择一个格子 $(x, y)$,在其所在的**整行和整列**的所有空格子中放置小球。
1. 选择一个格子 $(x, y)$,在经过该格子的**两条对角线**的所有空格子中放置小球。

即使一个格子中已经有小球,你依然可以选择该格子进行操作。
你需要求出**填满整个网格所需的最少操作次数**,并输出对应的具体操作方案。
**输入格式**
第一行为测试用例数量 $T$($1 \le T \le 10^4$)。
每个测试用例包含一行两个整数 $n, m$($1 \le n, m \le 10^3$),代表网格的行数和列数。
保证所有测试用例的 $n \times m$ 之和不超过 $10^6$。
**输出格式**
对于每个测试用例:
第一行输出最少操作次数 $p$($1 \le p \le n \times m$)。
随后 $p$ 行,每行输出三个整数 $op, x, y$($1 \le x \le n, 1 \le y \le m$),代表一次操作:
- 当 $op = 1$ 时,代表在格子 $(x, y)$ 进行行列的操作;
- 当 $op = 2$ 时,代表在格子 $(x, y)$ 进行对角线的操作。
**样例数据**
```
Input
2
3 4
2 2
Output
3
2 2 2
2 2 3
1 2 4
2
1 1 1
1 2 2
```
**样例解释针对第一组测试数据(**$3 \times 4$ **的网格):**
最少需要 $3$ 次操作。输出提供的方案如下:
- 第 $1$ 次操作:`2 2 2`,对 $(2, 2)$ 使用对角线操作。
- 第 $2$ 次操作:`2 2 3`,对 $(2, 3)$ 使用对角线操作。
- 第 $3$ 次操作:`1 2 4`,对 $(2, 4)$ 使用行列操作。
这 $3$ 次操作结束后,整个 $3 \times 4$ 的网格均会被小球覆盖。
**针对第二组测试数据(**$2 \times 2$ **的网格):**
最少需要 $2$ 次操作。输出提供的方案如下:
- 第 $1$ 次操作:`1 1 1`,对 $(1, 1)$ 使用行列操作,此时第 $1$ 行和第 $1$ 列被填满。
- 第 $2$ 次操作:`1 2 2`,对 $(2, 2)$ 使用行列操作,此时第 $2$ 行和第 $2$ 列被填满。
这 $2$ 次操作结束后,全部 $4$ 个格子均被填满。
## 思路讲解
赛时这个队友的这个思路,还是很厉害的。
**不难注意到,只有在 3*3 的网格上,对角线操作才可以减少操作数量。**
```cpp
void Solve() {
ll N, M;
cin >> N >> M;
ll opN = N, opM = M;
vector<array<ll,3>> ops;
for (int i = 1; i <= min(N, M); ++i) {
// 不难注意到,只有在 3*3 的网格上,对角线操作才可以减少操作数量
if (opN == 3 && opM == 3) {
// cout<<
ops.push_back({2,i+1,i+1});
ops.push_back({1,i+1,i+1});
break;
}
// cout << 1 << " " << i << " " << i << "\n";
ops.push_back({1,i,i});
opM--;
opN--;
}
cout<<SZ(ops)<<"\n";
for (auto [a,b,c]:ops) {
cout<<a<<" "<<b<<" "<<c<<"\n";
}
}
```
## AC代码
AC
[https://codeforces.com/gym/106139/submission/367213905](https://codeforces.com/gym/106139/submission/367213905)
::: 源代码
```cpp
/**
* Problem: D. Box
* Contest: The 21st Hunan Provincial Collegiate Programming Contest
* Judge: Codeforces
* URL: https://codeforces.com/gym/106139/problem/D
* Created: 2026-03-18 17:27:21
* Author: Gospel_rock
* My blog: https://znzryb.com/
*
* Powered by AutoCp https://github.com/Pushpavel/AutoCp
*/
#include <bits/stdc++.h>
#define all(vec) vec.begin(),vec.end()
#define lson(o) (o<<1)
#define rson(o) (o<<1|1)
#define SZ(a) ((long long) a.size())
#define debug(var) cerr << #var <<" = ["<<var<<"]"<<"\n";
#define debug1d(a) \
cerr << #a << " = ["; \
for (int i = 0; i < (int)(a).size(); i++) \
cerr << (i ? ", " : "") << a[i]; \
cerr << "]\n";
#define debug2d(a) \
cerr << #a << " = [\n"; \
for (int i = 0; i < (int)(a).size(); i++) \
{ \
cerr << " ["; \
for (int j = 0; j < (int)(a[i]).size(); j++) \
cerr << (j ? ", " : "") << a[i][j]; \
cerr << "]\n"; \
} \
cerr << "]\n";
#define cend cerr<<"\n-----------\n"
#define fsp(x) fixed<<setprecision(x)
using namespace std;
using ll = long long;
using ull = unsigned long long;
using DB = double;
using i128 = __int128;
using CD = complex<double>;
static constexpr ll MAXN = (ll) 1e6 + 10, INF = (1ll << 61) - 1;
static constexpr ll mod = 998244353; // (ll)1e9+7;
static constexpr double eps = 1e-8;
const double pi = acos(-1.0);
ll lT, testcase;
/*
*
*/
void Solve() {
ll N, M;
cin >> N >> M;
ll opN = N, opM = M;
vector<array<ll,3>> ops;
for (int i = 1; i <= min(N, M); ++i) {
if (opN == 3 && opM == 3) {
// cout<<
ops.push_back({2,i+1,i+1});
ops.push_back({1,i+1,i+1});
break;
}
// cout << 1 << " " << i << " " << i << "\n";
ops.push_back({1,i,i});
opM--;
opN--;
}
cout<<SZ(ops)<<"\n";
for (auto [a,b,c]:ops) {
cout<<a<<" "<<b<<" "<<c<<"\n";
}
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
#ifdef LOCAL
cout.setf(ios::unitbuf); // 无缓冲流,方便我们调试
#endif
cin >> lT;
for (testcase = 1; testcase <= lT; ++testcase)
Solve();
return 0;
}
/*
AC
https://codeforces.com/gym/106139/submission/367213905
*/
```
:::
## 心路历程(WA,TLE,MLE……)