牛客题解 | 模数求和
题目
解题思路
这是一道数学题目,主要思路如下:
-
问题分析:
- \(f(m) = (m\%a_1) + (m\%a_2) + ... + (m\%a_n)\)
- 需要找到一个 \(m\) 使 \(f(m)\) 最大
- \(a_i\) 的范围是 \([2, 10^5]\)
-
关键发现:
- 对于任意数 \(x\),\(x\%y\) 的结果一定小于 \(y\)
- 要使余数最大,\(m\) 应该比所有 \(a_i\) 都大
- 对于每个 \(a_i\),最大的余数是 \(a_i-1\)
-
解决方案:
- 对于每个输入的数 \(a_i\),最大可能的余数是 \(a_i-1\)
- 最终结果就是所有 \((a_i-1)\) 的和
代码
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
long long sum = 0;
for(int i = 0; i < n; i++) {
int a;
cin >> a;
sum += a - 1; // 每个数的最大余数
}
cout << sum << endl;
return 0;
}
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
long sum = 0;
for(int i = 0; i < n; i++) {
int a = sc.nextInt();
sum += a - 1; // 每个数的最大余数
}
System.out.println(sum);
}
}
def main():
n = int(input())
nums = list(map(int, input().split()))
# 计算所有最大余数之和
result = sum(x - 1 for x in nums)
print(result)
if __name__ == "__main__":
main()
算法及复杂度
- 算法:数学
- 时间复杂度:\(\mathcal{O}(n)\) - 只需要遍历一次输入数组
- 空间复杂度:\(\mathcal{O}(1)\) - 只需要常数级别的额外空间

浙公网安备 33010602011771号