题解:洛谷 AT_abc438_a First Contest of the Year
【题目来源】
洛谷:AT_abc438_a [ABC438A] First Contest of the Year - 洛谷
【题目描述】
在某颗星球上,一年有 \(D\) 天,并且每 \(7\) 天会举办一场比赛。比赛不会跨日举行。
某年的第一场比赛在该年的第 \(F\) 天举行。下一年的第一场比赛将在下一年的第几天举行?
在本题的约束条件下,保证下一年至少会举办一场比赛。
【输入】
输入一行,分别为 \(D,F\)。
【输出】
输出答案。
【输入样例】
365 4
【输出样例】
3
【核心思想】
-
问题分析:某星球一年有 \(D\) 天,每 \(7\) 天举办一场比赛。某年第一场比赛在第 \(F\) 天,求下一年第一场比赛在第几天。关键观察:比赛每 \(7\) 天一次,若第 \(F\) 天有比赛,则之后每 \(7\) 天都有。下一年第 \(1\) 天到第 \(7\) 天中必有一场,需要找到第一场。这是一个模运算 + 周期推算问题,核心在于利用 \(7\) 天周期计算下一年第一场比赛的日期。
-
算法选择:
- 模运算直接计算:下一年第一天是上一年的第 \(D+1\) 天(模 \(7\) 意义下)。第 \(F\) 天的星期为 \(F \bmod 7\),下一年第一天的星期为 \((D+1) \bmod 7\)。需要找下一年中第一个与 \(F\) 同星期的日子
-
关键步骤:
- 读入数据:\(D\)、\(F\)
- 计算星期偏移:
- 第 \(F\) 天的星期:\(w = F \bmod 7\)(或 \((F-1) \bmod 7 + 1\),取决于编号方式)
- 下一年第 \(1\) 天相对于第 \(F\) 天的偏移:\((D - F + 1) \bmod 7\)
- 下一年第一场比赛日期:\((7 - (D - F) \bmod 7) \bmod 7\),若结果为 \(0\) 则取 \(7\)
- 简化公式:答案 = \((7 - (D - F + 1) \bmod 7 + 1) \bmod 7\),调整至 \(1\)-\(7\) 范围
-
时间/空间复杂度:
- 时间复杂度:\(O(1)\)
- 空间复杂度:\(O(1)\)
-
模运算与周期推算的核心思想:
- 7天周期的连续性:比赛日期序列 \(F, F+7, F+14, \ldots\) 跨越年份边界。下一年第 \(k\) 天有比赛当且仅当 \((D + k) \equiv F \pmod{7}\),即 \(k \equiv F - D \pmod{7}\)
- 正数调整:模运算结果可能为负,需调整至 \([1, 7]\) 范围。代码中
(d - f) % 7在 C++ 中可能为负,需要正确处理 - 下一年保证有比赛:题目保证下一年至少一场比赛,因此答案必在 \(1\)-\(7\) 范围内
- 简化理解:从第 \(F\) 天到年底共 \(D - F + 1\) 天(含第 \(F\) 天),下一年第一天距离第 \(F\) 天为 \(D - F + 1\) 天。需要找最小的正整数 \(k\) 使得 \(D - F + 1 + k \equiv 0 \pmod{7}\),即 \(k \equiv F - D - 1 \pmod{7}\)
- 适用于基础模运算、周期推算类入门问题
【算法标签】
入门 #模拟
【代码详解】
#include <bits/stdc++.h>
using namespace std;
int d, f; // d: 今天是星期几,f: 今天是几号
int main()
{
// 输入:今天是星期几(d),今天是几号(f)
cin >> d >> f;
// 计算目标日期是星期几
// 核心公式:目标星期 = (当前星期 + 日期差) % 7
// 但题目要求输出距离下个星期d还有几天
int t = (d - f) % 7; // 计算当前日期与目标星期相差多少天
// 计算距离下一个目标星期还有几天
// 如果t是正数,表示已经过了,需要等7-t天
// 如果t是负数,取模后变成正数,但需要调整
cout << 7 - t << endl; // 输出距离下个星期d的天数
return 0;
}
【运行结果】
365 4
3
浙公网安备 33010602011771号