題目連結:
#include <bits/stdc++.h>
using namespace std;
int p[10], sum;
int main()
{
int A, B, C;
bool flag = false;
scanf("%d%d%d", &A, &B, &C);
for (int i = 1; i <= 999 / C; i++) {
memset(p, 0, sizeof p);
sum = 0;
int a = A * i, b = B * i, c = C * i;
int a1 = a % 10, a2 = (a / 10) % 10, a3 = (a / 100) % 10;
int b1 = b % 10, b2 = (b / 10) % 10, b3 = (b / 100) % 10;
int c1 = c % 10, c2 = (c / 10) % 10, c3 = (c / 100) % 10;
p[a1] = p[a2] = p[a3] = p[b1] = p[b2] = p[b3] = p[c1] = p[c2] = p[c3] = 1;
for (int i = 1; i <= 9; i++) sum += p[i];
if (sum == 9) {
printf("%d %d %d", a, b, c);
flag = true;
puts("");
}
}
if (!flag) puts("No!!!");
return 0;
}
值得一提的是,之所以用 \(A*i、B*i、C*i\) 而不是列舉第一個數 \(x\) 再去計算 \(B / A * x\) 和 \(C / A * x\),是因為若 \(A=0\) 處理起來會比較麻煩,同時 \(B / A\) 和 \(C / A\) 會導致精度不夠的問題,因此換乘為除。
需要注意的是,本題一開始還有另外一個 \(AC\) 程式碼:
#include <cstdio>
#include <set>
int main()
{
int A, B, C;
std::set<int> s;
bool flag = false;
scanf("%d%d%d", &A, &B, &C);
for (int i = 1; i <= 999 / C; i++) {
if (A != 0) {
s.clear();
int a = A * i, b = B * i, c = C * i;
int a1 = a % 10, a2 = (a / 10) % 10, a3 = (a / 100) % 10;
int b1 = b % 10, b2 = (b / 10) % 10, b3 = (b / 100) % 10;
int c1 = c % 10, c2 = (c / 10) % 10, c3 = (c / 100) % 10;
s.insert(a1);
s.insert(a2);
s.insert(a3);
s.insert(b1);
s.insert(b2);
s.insert(b3);
s.insert(c1);
s.insert(c2);
s.insert(c3);
if (s.size() == 9 && a1 + a2 + a3 + b1 + b2 + b3 + c1 + c2 + c3 == 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 && a1 * a2 * a3 * b1 * b2 * b3 * c1 * c2 * c3 == 1 * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9) {
printf("%d %d %d", a, b, c);
flag = true;
puts("");
}
}
else {
puts("No!!!");
return 0;
}
}
if (!flag) puts("No!!!");
return 0;
}
其利用的數學知識為:在集合元素個數相同的情況下,若兩個集合中的所有元素之和、之積均相等,則這兩個集合相等。
但這個原理在某些情況下不滿足,比如 \((-4, 0, 4)\) 和 \((-5, 0, 5)\)、\((0, 1, 2)\) 和 \((0, 3)\)。所以只當沒有辦法的時候可以考慮用這個定理來騙分。