1 条题解
-
0
这是一个完整的 C++ 数据生成器,用于生成“序列操作(区间加法)”题目的测试数据。
它包含了一个标准的差分数组解法,用于生成正确的
.out文件,并设计了 10 个测试点,覆盖了从样例、边界情况(单点修改、全区间修改)到最大规模压力测试的各种场景。数据生成器代码 (generator.cpp)
您可以将以下代码保存为
generator.cpp,编译并运行。它将在当前目录下生成1.in/1.out到10.in/10.out。#include <iostream> #include <fstream> #include <vector> #include <string> #include <random> #include <ctime> #include <algorithm> using namespace std; typedef long long ll; struct Operation { int l, r, v; }; // ========================================== // 1. 标准解法函数 (用于生成 .out 文件) // ========================================== // 使用差分数组算法 O(N+K) vector<ll> solve(int n, int k, const vector<Operation>& ops) { // 差分数组,大小开 N+2 以防 R=N 时 R+1 越界 vector<ll> diff(n + 2, 0); for (const auto& op : ops) { diff[op.l] += op.v; diff[op.r + 1] -= op.v; } vector<ll> result; ll current_val = 0; for (int i = 1; i <= n; ++i) { current_val += diff[i]; result.push_back(current_val); } return result; } // ========================================== // 2. 随机数辅助工具 // ========================================== mt19937 rng(time(nullptr)); // 生成 [min, max] 范围内的随机整数 int random_int(int min, int max) { uniform_int_distribution<int> dist(min, max); return dist(rng); } // ========================================== // 3. 测试点生成逻辑 // ========================================== void generate_test_case(int id) { int N, K; int min_v, max_v; string desc; // 根据 id 设定测试点参数 switch (id) { case 1: // 样例数据 N = 5; K = 3; min_v = 0; max_v = 0; // 这里的范围无效,因为下面会硬编码 desc = "Sample Case"; break; case 2: // 极小数据 N = 10; K = 5; min_v = -10; max_v = 10; desc = "Small N, Small K"; break; case 3: // 单点修改 (L=R) N = 100; K = 50; min_v = 1; max_v = 100; desc = "Single Point Updates (L=R)"; break; case 4: // 全区间修改 (L=1, R=N) N = 100; K = 50; min_v = -50; max_v = 50; desc = "Full Range Updates (L=1, R=N)"; break; case 5: // 全正数累加 N = 1000; K = 1000; min_v = 1; max_v = 1000; desc = "All Positive V"; break; case 6: // 全负数累加 N = 1000; K = 1000; min_v = -1000; max_v = -1; desc = "All Negative V"; break; case 7: // 混合随机 N = 5000; K = 5000; min_v = -1000; max_v = 1000; desc = "Mixed Random"; break; case 8: // 大 N 小 K (稀疏操作) N = 100000; K = 10; min_v = -1000; max_v = 1000; desc = "Large N, Small K"; break; case 9: // 小 N 大 K (密集操作) N = 10; K = 100000; min_v = -100; max_v = 100; desc = "Small N, Large K"; break; case 10: // 最大规模压力测试 N = 100000; K = 100000; min_v = -1000; max_v = 1000; desc = "Max Constraints (N=10^5, K=10^5)"; break; default: N = 10; K = 10; min_v = 1; max_v = 10; } vector<Operation> ops; // 特殊处理样例数据 if (id == 1) { ops = { {1, 3, 2}, {2, 4, 3}, {3, 5, -2} }; } else { for (int i = 0; i < K; ++i) { int l, r, v; v = random_int(min_v, max_v); if (id == 3) { // 单点 l = random_int(1, N); r = l; } else if (id == 4) { // 全区间 l = 1; r = N; } else { // 随机区间 int p1 = random_int(1, N); int p2 = random_int(1, N); l = min(p1, p2); r = max(p1, p2); } ops.push_back({l, r, v}); } } // --- 写入 .in 文件 --- string in_filename = to_string(id) + ".in"; ofstream fin(in_filename); fin << N << " " << K << "\n"; for (const auto& op : ops) { fin << op.l << " " << op.r << " " << op.v << "\n"; } fin.close(); // --- 计算答案并写入 .out 文件 --- vector<ll> result = solve(N, K, ops); string out_filename = to_string(id) + ".out"; ofstream fout(out_filename); for (int i = 0; i < N; ++i) { fout << result[i] << (i == N - 1 ? "" : " "); } fout << "\n"; // 文末换行 fout.close(); cout << "Generated Case " << id << ": " << desc << " (N=" << N << ", K=" << K << ")" << endl; } int main() { // 加速 I/O ios::sync_with_stdio(false); for (int i = 1; i <= 10; ++i) { generate_test_case(i); } cout << "All test cases generated successfully!" << endl; return 0; }测试点详细设计说明
- Case 1 (Sample): 题目描述中的样例,用于最基础的逻辑验证。
- Case 2 (Small Scale): 。简单的小数据,方便人工排查问题。
- Case 3 (Single Point): 。退化为单点修改,验证差分操作在区间长度为1时是否正确(
diff[l]+=v, diff[l+1]-=v)。 - Case 4 (Full Range): 。每次都修改整个数组,验证边界处理(尤其是
diff[N+1]是否越界)。 - Case 5 (All Positive): 。验证数值累加逻辑。
- Case 6 (All Negative): 。验证数值相减逻辑。
- Case 7 (Mixed): 有正有负。验证正负抵消后的结果。
- Case 8 (Large N, Small K): 。稀疏操作,大部分元素可能为 0,测试大数组的初始化和输出。
- Case 9 (Small N, Large K): 。密集操作,每个点被修改非常多次,测试累加后的数值是否溢出
int(虽然题目保证了范围,但解法应使用long long保证鲁棒性)。 - Case 10 (Stress Test): 。最大规模压力测试,验证算法的时间复杂度是否为 。如果使用暴力 解法,此点会超时。
如何使用
- 保存:将代码保存为
generator.cpp。 - 编译:
g++ generator.cpp -o generator -O2 - 运行:
./generator(Linux/Mac) 或generator.exe(Windows)。 - 结果:当前文件夹下会生成
1.in/1.out到10.in/10.out共 20 个文件。您可以直接将这些文件打包上传到 OJ(Online Judge)系统的后台作为评测数据。
- 1
信息
- ID
- 19323
- 时间
- 1000ms
- 内存
- 32MiB
- 难度
- 10
- 标签
- (无)
- 递交数
- 1
- 已通过
- 1
- 上传者