问题描述
商家使用了循环订单编号系统,每次发起订单时,编号会递增,但当编号超过设置的上限 mm 时,编号会从 11 重新开始编号。小M想知道,当编号上限为 mm 时,第 xx 个订单的编号是多少。
你需要处理多个查询,每个查询给定 mm 和 xx,输出第 xx 个订单的编号。
测试样例
样例1:
输入:
m = 2, x = 3
输出:1
样例2:
输入:
m = 5, x = 17
输出:2
样例3:
输入:
m = 8, x = 2
输出:2
样例4:
输入:
m = 4, x = 4
输出:4
以下是解题思路:
解题思路
这个问题的核心在于理解循环编号的规律,以及如何高效计算循环中的位置。根据题意:
- 编号从 11 开始,每次递增。
- 当编号达到上限 mm,下一次编号从 11 重新开始。
- 编号规律:编号以 mm 为周期,按照 1,2,...,m1, 2, ..., m 循环重复。
为了高效计算第 xx 个订单的编号,可以使用数学公式来解决。
公式推导
- 假设订单编号的序列为 1,2,...,m,1,2,...,m1, 2, ..., m, 1, 2, ..., m(无限循环)。
- 为了找出第 xx 个订单的编号,可以将序号从 11 开始的编号转化为以 mm 为周期的位置: 编号=(x−1)mod m+1\text{编号} = (x - 1) \mod m + 1
公式解释:
- x−1x - 1:将序号从 11 开始的编号调整为从 00 开始(方便处理循环)。
- mod m\mod m:对 mm 取模,得到当前序号在一个周期内的偏移量。
- +1+1:将偏移量调整回从 11 开始的编号。
算法步骤
- 检查输入的合法性(如 m>0,x>0m > 0, x > 0)。
- 使用公式 (x−1)mod m+1(x - 1) \mod m + 1 计算编号。
- 返回计算结果。
复杂度分析
- 时间复杂度:O(1)O(1),因为只涉及一次取模运算。
- 空间复杂度:O(1)O(1),不需要额外空间。
代码实现
def solution(m: int, x: int) -> int:
"""
计算第 x 个订单的编号。
参数:
m (int): 编号上限
x (int): 第 x 个订单
返回:
int: 第 x 个订单的编号
"""
return (x - 1) % m + 1
# 测试样例
if __name__ == '__main__':
# 测试用例与预期输出
print(solution(2, 3) == 1) # 第 3 个订单编号为 1
print(solution(5, 17) == 2) # 第 17 个订单编号为 2
print(solution(8, 2) == 2) # 第 2 个订单编号为 2
print(solution(4, 4) == 4) # 第 4 个订单编号为 4
测试样例详解
示例 1
- 输入:m=2,x=3m = 2, x = 3
- 计算: 编号=(3−1)mod 2+1=2mod 2+1=0+1=1\text{编号} = (3 - 1) \mod 2 + 1 = 2 \mod 2 + 1 = 0 + 1 = 1
- 输出:11
示例 2
- 输入:m=5,x=17m = 5, x = 17
- 计算: 编号=(17−1)mod 5+1=16mod 5+1=1+1=2\text{编号} = (17 - 1) \mod 5 + 1 = 16 \mod 5 + 1 = 1 + 1 = 2
- 输出:22
示例 3
- 输入:m=8,x=2m = 8, x = 2
- 计算: 编号=(2−1)mod 8+1=1mod 8+1=1+1=2\text{编号} = (2 - 1) \mod 8 + 1 = 1 \mod 8 + 1 = 1 + 1 = 2
- 输出:22
示例 4
- 输入:m=4,x=4m = 4, x = 4
- 计算: 编号=(4−1)mod 4+1=3mod 4+1=3+1=4\text{编号} = (4 - 1) \mod 4 + 1 = 3 \mod 4 + 1 = 3 + 1 = 4
- 输出:44
总结
- 通过数学公式 (x−1)mod m+1(x - 1) \mod m + 1,我们能够快速计算循环编号。
- 时间复杂度和空间复杂度均为 O(1)O(1),算法高效。
- 这种方法适用于所有正整数 mm 和 xx,非常通用。