1 条题解
-
0
标准题解代码 (NOIP C++14)
/** * 题目:环球飞行 (Global Flight) * 难度:GESP 4级 / CSP-J 普及- * 知识点:模拟、模运算、时间换算 */ #include <iostream> #include <cstdio> // 用于 printf 格式化输出 using namespace std; int main() { // 提升 cin 速度 ios::sync_with_stdio(false); cin.tie(NULL); int N, Z_curr, H, M; if (!(cin >> N >> Z_curr >> H >> M)) return 0; // 核心思路:将所有时间转化为相对于【第0天 00:00】的【总分钟数】 // 使用 long long 防止溢出(虽然本题数据范围 int 足够,但这是好习惯) // 初始总分钟数 = 小时*60 + 分钟 long long total_minutes = (long long)H * 60 + M; // 循环处理 N 段航程 for (int i = 0; i < N; ++i) { int h_fly, m_fly, z_next; cin >> h_fly >> m_fly >> z_next; // 1. 加上物理飞行时间 total_minutes += (h_fly * 60 + m_fly); // 2. 加上时差影响 // 时差 = 新时区 - 旧时区 // 例如从 +8 到 -5: (-5) - 8 = -13 小时,即时间要倒退 13 小时 int time_diff = z_next - Z_curr; total_minutes += time_diff * 60; // 更新当前所在时区 Z_curr = z_next; } // 计算最终结果 const int MINUTES_PER_DAY = 24 * 60; // 1440 分钟 // 1. 计算天数 Day // 难点:处理负数。例如 -100 分钟,应该是 Day -1 的 22:20。 // C++ 中整数除法 -100 / 1440 = 0,但这不符合日期的逻辑(我们需要向下取整) long long day; if (total_minutes >= 0) { day = total_minutes / MINUTES_PER_DAY; } else { // 对于负数,如果能整除(如 -1440),就是 Day -1 // 如果不能整除(如 -100),也是 Day -1 // 通用向下取整公式: floor(a/b) // 手写逻辑: if (total_minutes % MINUTES_PER_DAY == 0) { day = total_minutes / MINUTES_PER_DAY; } else { day = total_minutes / MINUTES_PER_DAY - 1; } } // 2. 计算当天的小时和分钟 // 难点:处理负数取模。C++ 中 -100 % 1440 = -100。 // 我们需要的是正的时刻。公式:((a % b) + b) % b int minute_of_day = (total_minutes % MINUTES_PER_DAY + MINUTES_PER_DAY) % MINUTES_PER_DAY; int final_h = minute_of_day / 60; int final_m = minute_of_day % 60; // 输出,注意补前导0 printf("Day %lld %02d:%02d\n", day, final_h, final_m); return 0; }
数据生成器 (Data Generator)
这是配套的测试数据生成器,修正了样例数据的逻辑,并覆盖了跨天、负数日期等边界情况。
#include <iostream> #include <fstream> #include <vector> #include <string> #include <cstdio> using namespace std; // 解决逻辑 void solve(int N, int Z_curr, int H, int M, const vector<vector<int>>& flights, ofstream& fout) { long long total = (long long)H * 60 + M; for(const auto& f : flights) { int h_fly = f[0]; int m_fly = f[1]; int z_next = f[2]; total += (h_fly * 60 + m_fly); total += (z_next - Z_curr) * 60; Z_curr = z_next; } const int DAY_MIN = 1440; long long day; if(total >= 0) day = total / DAY_MIN; else { if(total % DAY_MIN == 0) day = total / DAY_MIN; else day = total / DAY_MIN - 1; } int m_day = (total % DAY_MIN + DAY_MIN) % DAY_MIN; int fh = m_day / 60; int fm = m_day % 60; // 手动格式化输出到文件 fout << "Day " << day << " "; if(fh < 10) fout << "0"; fout << fh << ":"; if(fm < 10) fout << "0"; fout << fm << endl; } int main() { // 构造 10 个测试点 for(int i = 1; i <= 10; ++i) { string in_name = to_string(i) + ".in"; string out_name = to_string(i) + ".out"; ofstream fin(in_name); ofstream fout(out_name); int N, Z0, H0, M0; vector<vector<int>> flights; // 生成数据策略 if (i == 1) { // 样例1 N=2; Z0=8; H0=9; M0=30; flights = {{12,0,-5}, {3,30,8}}; } else if (i == 2) { // 样例2 N=1; Z0=0; H0=23; M0=0; flights = {{2,0,-1}}; } else if (i == 3) { // 负数日期测试:往西飞,倒时差 N=2; Z0=0; H0=1; M0=0; // 1:00起飞,飞1小时,去-5区 -> 1+1-5 = -3:00 -> Day -1 21:00 flights = {{1,0,-5}, {0,0,-5}}; } else if (i == 4) { // 跨多天测试 N=5; Z0=0; H0=0; M0=0; // 每次飞20小时 for(int k=0; k<5; k++) flights.push_back({20, 0, 0}); } else { // 随机数据 N = rand() % 10 + 1; Z0 = rand() % 24 - 11; H0 = rand() % 24; M0 = rand() % 60; int z_prev = Z0; for(int k=0; k<N; k++) { int hf = rand() % 15; int mf = rand() % 60; int zn = rand() % 24 - 11; flights.push_back({hf, mf, zn}); } } // 写入输入 fin << N << " " << Z0 << " " << H0 << " " << M0 << endl; for(auto& f : flights) { fin << f[0] << " " << f[1] << " " << f[2] << endl; } // 写入输出 solve(N, Z0, H0, M0, flights, fout); fin.close(); fout.close(); cout << "Generated Case " << i << endl; } return 0; }
- 1
信息
- ID
- 19274
- 时间
- 1000ms
- 内存
- 32MiB
- 难度
- 10
- 标签
- (无)
- 递交数
- 1
- 已通过
- 1
- 上传者