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> #include <tuple> using namespace std; typedef long long ll; // 预订记录结构: first, last, seats struct Booking { int l, r, v; }; // ========================================== // 1. 标准解法函数 (用于生成 .out 文件) // ========================================== // 使用差分数组算法 O(N+M) vector<ll> solve(int n, const vector<Booking>& bookings) { // 差分数组,大小开 N+2 以防 r=N 时 r+1 越界 vector<ll> diff(n + 2, 0); for (const auto& b : bookings) { diff[b.l] += b.v; diff[b.r + 1] -= b.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, M; int max_seats; string desc; // 根据 id 设定测试点参数 // 题目限制: N, M <= 2*10^5, Seats <= 10000 switch (id) { case 1: // 样例数据 N = 5; M = 3; max_seats = 0; // 这里的范围无效,因为下面会硬编码 desc = "Sample Case"; break; case 2: // 极小数据 N = 10; M = 5; max_seats = 100; desc = "Small N, Small M"; break; case 3: // 单点修改 (L=R) - 测试最小区间 N = 1000; M = 1000; max_seats = 1000; desc = "Single Point Updates (L=R)"; break; case 4: // 全区间修改 (L=1, R=N) - 测试最大区间 N = 1000; M = 1000; max_seats = 1000; desc = "Full Range Updates (L=1, R=N)"; break; case 5: // 只有一架飞机 N = 1; M = 1000; max_seats = 1000; desc = "N=1 Boundary"; break; case 6: // 很多飞机,很少预订 (稀疏) N = 200000; M = 10; max_seats = 10000; desc = "Large N, Small M"; break; case 7: // 中等规模随机 N = 50000; M = 50000; max_seats = 5000; desc = "Medium Random"; break; case 8: // 大数据 - 随机区间 N = 200000; M = 200000; max_seats = 1000; desc = "Max Constraints Random"; break; case 9: // 大数据 - 溢出测试 (Seats最大) // 2*10^5 * 10000 = 2*10^9, 接近 int 上限,累加后必超 int N = 200000; M = 200000; max_seats = 10000; desc = "Max Constraints Max Seats (long long check)"; break; case 10: // 大数据 - 后半段集中 N = 200000; M = 200000; max_seats = 5000; desc = "Heavy Load on Second Half"; break; default: N = 10; M = 10; max_seats = 100; } vector<Booking> bookings; // 特殊处理样例数据 if (id == 1) { bookings = { {1, 2, 10}, {2, 3, 20}, {2, 5, 25} }; } else { for (int i = 0; i < M; ++i) { int l, r, v; v = random_int(1, max_seats); if (id == 3) { // 单点 l = random_int(1, N); r = l; } else if (id == 4 || id == 5) { // 全区间 或 N=1 l = 1; r = N; } else if (id == 10) { // 后半段集中 int half = N / 2; if (half < 1) half = 1; // 80% 的概率落在后半段 if (random_int(1, 10) <= 8) { int p1 = random_int(half, N); int p2 = random_int(half, N); l = min(p1, p2); r = max(p1, p2); } else { int p1 = random_int(1, N); int p2 = random_int(1, N); l = min(p1, p2); r = max(p1, p2); } } else { // 常规随机 int p1 = random_int(1, N); int p2 = random_int(1, N); l = min(p1, p2); r = max(p1, p2); } bookings.push_back({l, r, v}); } } // --- 写入 .in 文件 --- string in_filename = to_string(id) + ".in"; ofstream fin(in_filename); fin << N << " " << M << "\n"; for (const auto& b : bookings) { fin << b.l << " " << b.r << " " << b.v << "\n"; } fin.close(); // --- 计算答案并写入 .out 文件 --- vector<ll> result = solve(N, bookings); 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 << ", M=" << M << ")" << 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): 。退化为单点修改,验证差分操作
diff[l] += v, diff[l+1] -= v的正确性。 - Case 4 (Full Range): 。每次都覆盖整个数组,验证边界处理(尤其是
diff[N+1]是否越界)。 - Case 5 (N=1 Boundary): 只有一架飞机。这是 的下界,验证程序是否能处理最小 。
- Case 6 (Sparse): 。大规模 但操作很少,大部分位置结果为 0,测试大数组的初始化和输出效率。
- Case 7 (Medium): 。常规的中等规模随机测试。
- Case 8 (Max Constraints): 。最大规模压力测试,验证 算法的时间效率。
- Case 9 (Overflow Check): 最大规模,且座位数均为最大值 ()。总座位数可能达到 ,如果累加稍微多一点就会超过
int上限(21亿),强制要求解题者使用long long。 - Case 10 (Skewed Distribution): 后半段区间操作密集。测试在不均匀分布下的正确性。
使用方法
- 保存:将代码保存为
generator.cpp。 - 编译:
g++ generator.cpp -o generator -O2 - 运行:
./generator - 结果:当前文件夹下会生成
1.in,1.out到10.in,10.out。可以直接上传到 OJ 系统。
- 1
信息
- ID
- 19324
- 时间
- 1000ms
- 内存
- 32MiB
- 难度
- 10
- 标签
- (无)
- 递交数
- 1
- 已通过
- 1
- 上传者