题目大意
题目描述
给定一个 n×m 的初始为空的网格,你可以进行以下两种操作:
-
选择一个格子 (x,y),在其所在的整行和整列的所有空格子中放置小球。
-
选择一个格子 (x,y),在经过该格子的两条对角线的所有空格子中放置小球。

即使一个格子中已经有小球,你依然可以选择该格子进行操作。
你需要求出填满整个网格所需的最少操作次数,并输出对应的具体操作方案。
输入格式
第一行为测试用例数量 T(1≤T≤104)。
每个测试用例包含一行两个整数 n,m(1≤n,m≤103),代表网格的行数和列数。
保证所有测试用例的 n×m 之和不超过 106。
输出格式
对于每个测试用例:
第一行输出最少操作次数 p(1≤p≤n×m)。
随后 p 行,每行输出三个整数 op,x,y(1≤x≤n,1≤y≤m),代表一次操作:
-
当 op=1 时,代表在格子 (x,y) 进行行列的操作;
-
当 op=2 时,代表在格子 (x,y) 进行对角线的操作。
样例数据
1 2 3 4 5 6 7 8 9 10 11 12 13
| 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×4 的网格):
最少需要 3 次操作。输出提供的方案如下:
-
第 1 次操作:2 2 2,对 (2,2) 使用对角线操作。
-
第 2 次操作:2 2 3,对 (2,3) 使用对角线操作。
-
第 3 次操作:1 2 4,对 (2,4) 使用行列操作。
这 3 次操作结束后,整个 3×4 的网格均会被小球覆盖。
针对第二组测试数据(2×2 的网格):
最少需要 2 次操作。输出提供的方案如下:
-
第 1 次操作:1 1 1,对 (1,1) 使用行列操作,此时第 1 行和第 1 列被填满。
-
第 2 次操作:1 2 2,对 (2,2) 使用行列操作,此时第 2 行和第 2 列被填满。
这 2 次操作结束后,全部 4 个格子均被填满。
思路讲解
赛时这个队友的这个思路,还是很厉害的。
不难注意到,只有在 3*3 的网格上,对角线操作才可以减少操作数量。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| 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) { ops.push_back({2,i+1,i+1}); ops.push_back({1,i+1,i+1}); break; } 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
源代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
|
#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; 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) { ops.push_back({2,i+1,i+1}); ops.push_back({1,i+1,i+1}); break; } 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; }
|
心路历程(WA,TLE,MLE……)