把 52 周存钱总额化为 N=364X+1092K,从大到小枚举 X 找到合法 K。
OJ: luogu
题目 ID: P4956
难度:入门
标签:数学枚举python
日期: 2026-07-15 18:39
题意
每周七天存的钱分别是:
text
X, X+K, X+2K, ..., X+6K一共存 52 周,给出总额 N,求满足条件的 X 和 K。如果有多组答案,要求输出最大的 X,同时 K 最小。
思路
先把一周的总额合并:
text
7X + (0+1+2+3+4+5+6)K = 7X + 21K一年 52 周,所以:
text
N = 52 * (7X + 21K) = 364X + 1092K题目限制 X <= 100,范围很小。为了得到最大的 X,直接从 100 到 0 倒着枚举 X。对每个 X,检查剩下的钱是否能被 1092 整除,且 K > 0。
第一个找到的合法 X 就是最大 X,对应的 K 也满足题目要求。
这题的枚举空间很小,正解已经是直接枚举,不创建额外 brute.py。
Python 知识
/home/rainboy/mycode/hugo-blog/content/program_language/python/input_output_and_strings.md:用int(input())读取总额。/home/rainboy/mycode/hugo-blog/content/program_language/python/math_tools.md:本题只用整数加减乘除,Pythonint足够稳定。range(100, -1, -1)表示从100倒着枚举到0。rest % 1092 == 0用来判断能否整除。
代码
python
target = int(input())
for x in range(100, -1, -1):
rest = target - 364 * x
if rest > 0 and rest % 1092 == 0:
k = rest // 1092
print(x)
print(k)
breakcpp
/**
* Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
* rbook: -> https://rbook.roj.ac.cn https://rbook2.roj.ac.cn
* rainboy的学习导航网站: https://idx.roj.ac.cn
* create_at: 2026-07-27 00:00
* update_at: 2026-07-27 00:00
*/
#include <bits/stdc++.h>
using namespace std;
int main() {
int N; // 一年存的总钱数
cin >> N;
// 代数化简后:N = 364 * X + 1092 * K
// 要输出最大的 X,所以从 100 倒着枚举
for (int x = 100; x >= 0; x--) {
int rest = N - 364 * x;
// 剩下的钱要能被 1092 整除,且 K > 0
if (rest > 0 && rest % 1092 == 0) {
int k = rest / 1092;
cout << x << endl << k << endl;
break;
}
}
return 0;
}复杂度
最多枚举 101 个 X,时间复杂度是
总结
这题先做代数化简,再利用 X 范围很小倒序枚举。倒序枚举让“最大 X”这个要求自然满足。