1 条题解
-
0
这是一个完整的 OI 风格数据生成器(Data Generator)。这段代码会利用**标准解法(Standard Solution)**作为核心逻辑,自动生成
1.in/1.out到10.in/10.out共 20 个文件。数据生成策略设计
为了保证测试数据的强度和覆盖面,设计了以下 10 个测试点:
- #1 (极小数据):,用于肉眼检查。
- #2 (小规模随机):,普通随机。
- #3 (全部相等):,所有元素值相同(边界:答案应全为 -1)。
- #4 (严格单调递增):,类似
1 2 3 ... N(边界:环形特性的基本测试)。 - #5 (严格单调递减):,类似
N ... 3 2 1(边界:所有非最大值的下一个更大元素都是首元素)。 - #6 (大波浪):,数值在 1 到 100 之间波动(测试重复数值处理)。
- #7 (大规模随机):,数值范围 (常规压力测试)。
- #8 (大规模随机):,同上,验证随机性。
- #9 (极端峰值):,只有一个极大值,其余极小(测试栈的弹出性能)。
- #10 (锯齿波):,大小交替
10 1000 10 1000...(最坏情况之一,频繁入栈出栈)。
Generator 代码 (C++14)
请将以下代码保存为
gen.cpp,编译并运行即可在当前目录下生成所有测试数据文件。#include <bits/stdc++.h> using namespace std; // ========================================== // Part 1: 标准解答 (Standard Solution) // 用于生成 .out 文件 // ========================================== vector<int> solve(int n, const vector<int>& nums) { vector<int> res(n, -1); stack<int> s; // 2*n - 1 倒序遍历,模拟环形 for (int i = 2 * n - 1; i >= 0; --i) { int realIndex = i % n; while (!s.empty() && s.top() <= nums[realIndex]) { s.pop(); } if (i < n) { if (!s.empty()) { res[realIndex] = s.top(); } else { res[realIndex] = -1; } } s.push(nums[realIndex]); } return res; } // ========================================== // Part 2: 数据生成器工具 (Generator Tools) // ========================================== mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); // 生成 [L, R] 范围内的随机整数 int random_int(int L, int R) { return uniform_int_distribution<int>(L, R)(rng); } // 生成指定模式的数据 vector<int> generate_data(int case_id) { int n; vector<int> a; switch (case_id) { case 1: // 极小数据,便于手算验证 n = 5; for(int i=0; i<n; i++) a.push_back(random_int(1, 10)); break; case 2: // 小规模随机 n = 100; for(int i=0; i<n; i++) a.push_back(random_int(1, 1000)); break; case 3: // 全部相等 (边界情况) n = 1000; { int val = random_int(1, 1000); for(int i=0; i<n; i++) a.push_back(val); } break; case 4: // 严格单调递增 (测试环形逻辑) n = 2000; for(int i=0; i<n; i++) a.push_back(i + 1); break; case 5: // 严格单调递减 (测试环形回绕) n = 2000; for(int i=0; i<n; i++) a.push_back(n - i); break; case 6: // 大规模,小数值范围 (大量重复元素) n = 50000; for(int i=0; i<n; i++) a.push_back(random_int(1, 50)); break; case 7: // 最大规模随机 A n = 100000; for(int i=0; i<n; i++) a.push_back(random_int(1, 1000000000)); break; case 8: // 最大规模随机 B n = 100000; for(int i=0; i<n; i++) a.push_back(random_int(1, 1000000000)); break; case 9: // 只有一个峰值 (其余都很小) n = 100000; for(int i=0; i<n; i++) a.push_back(random_int(1, 100)); a[random_int(0, n-1)] = 1000000000; // 插入一个极大值 break; case 10: // 锯齿波 (大小交替,考验栈的频繁操作) n = 100000; for(int i=0; i<n; i++) { if (i % 2 == 0) a.push_back(10); else a.push_back(100000); } break; default: n = 10; for(int i=0; i<n; i++) a.push_back(i); } return a; } // ========================================== // Part 3: 主程序 // ========================================== int main() { // 循环生成 1 到 10 号测试点 for (int i = 1; i <= 10; ++i) { string in_file_name = to_string(i) + ".in"; string out_file_name = to_string(i) + ".out"; cout << "Generating Case " << i << "..." << endl; // 1. 生成数据 vector<int> data = generate_data(i); int n = data.size(); // 2. 写入 .in 文件 ofstream fin(in_file_name); fin << n << "\n"; for (int k = 0; k < n; ++k) { fin << data[k] << (k == n - 1 ? "" : " "); } fin << "\n"; fin.close(); // 3. 计算答案并写入 .out 文件 vector<int> ans = solve(n, data); ofstream fout(out_file_name); for (int k = 0; k < n; ++k) { fout << ans[k] << (k == n - 1 ? "" : " "); } fout << "\n"; fout.close(); } cout << "All 10 test cases generated successfully." << endl; return 0; }使用说明
- 环境准备:确保你有 C++ 编译器(如
g++)。 - 编译:
g++ gen.cpp -o gen -std=c++14 -O2 - 运行:
- Windows:
gen.exe - Linux/Mac:
./gen
- Windows:
- 结果:
- 程序运行结束后,你的文件夹里会出现
1.in,1.out...10.in,10.out。 - 你可以直接将这些文件压缩上传到 OJ 后台(如 Hydro, Luogu 等)。
- 程序运行结束后,你的文件夹里会出现
检查点验证
- Case 3 (All Equal): 打开
3.out,内容应该全是-1。 - Case 4 (Sorted Asc): 打开
4.out,例如1 2 3,输出应为2 3 -1。 - Case 5 (Sorted Desc): 打开
5.out,例如3 2 1,输出应为-1 3 3。 - Case 10 (Sawtooth): 锯齿波能有效检测程序在极端波动下的鲁棒性。
这套数据生成器完全覆盖了题目所需的各类情况。
- 1
信息
- ID
- 19264
- 时间
- 1000ms
- 内存
- 32MiB
- 难度
- (无)
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者