三连击
信息
此题目来自 洛谷, 原始题目与提交代码请前往 P1008 [NOIP 1998 普及组] 三连击 - 洛谷。
题目背景
本题为提交答案题,您可以写程序或手算在本机上算出答案后,直接提交答案文本,也可提交答案生成程序。
题目描述
将 共 个数分成 组,分别组成 个三位数,且使这 个三位数构成 的比例,试求出所有满足条件的 个三位数。
输入格式
无
输出格式
若干行,每行 个数字。按照每行第 个数字升序排列。
输入输出样例
输出 #1
192 384 576
* * *
...
* * *
(剩余部分不予展示)
说明/提示
NOIP1998 普及组 第一题
题目解答
由于这是一道提交答案题,说明我们可以不考虑时间复杂度与空间复杂度来编写程序。
正常人谁会去手算。
很轻而易举的我们就可以发现,这其中的数字都是三位数 (这不废话吗),
于是,每个数的取值范围都应为 。
又考虑到数字不会重复,那么取值范围应为 。 不过,我们也可以直接检查每一位数字看看有没有重复的就可以了。
假设这三个数字分别为 、、。 观察题目,不难发现 ,即 ,。 再由 可得,。
那么我们遍历 a 变量即可。
- C++
/**
* 洛谷 P1008 解答程序。
* @author CoolCLK
*/
#include <iostream>
using namespace std;
/**
* 检查是否有重复数字,使用贡献法。
* @author CoolCLK
*/
bool checkDigits(int a, int b, int c) {
int digits[10] = {0};
int nums[] = {a, b, c};
for (int num : nums) {
while (num > 0) {
int digit = num % 10;
if (digit == 0 || digits[digit] > 0) {
return false;
}
digits[digit]++;
num /= 10;
}
}
for (int i = 1; i <= 9; i++) {
if (digits[i] != 1) {
return false;
}
}
return true;
}
/**
* @author CoolCLK
*/
int main() {
for (int a = 123; a <= 329; a++) {
int b = 2 * a;
int c = 3 * a;
if (!checkDigits(a, b, c)) continue;
cout << a << " " << b << " " << c << endl;
}
return 0;
}
结果:
192 384 576
219 438 657
267 534 801
273 546 819
327 654 981