题目链接:
#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)\)。所以只当没有办法的时候可以考虑用这个定理来骗分。
标签:main,连击,false,int,d%,bool,P1618,include,升级版 From: https://www.cnblogs.com/pangyou3s/p/18107713