一、问题引出
三连击(升级版)
题目描述
将
1
,
2
,
…
,
9
1, 2,\ldots, 9
1,2,…,9 共
9
9
9 个数分成三组,分别组成三个三位数,且使这三个三位数的比例是
A
:
B
:
C
A:B:C
A:B:C,试求出所有满足条件的三个三位数,若无解,输出 No!!!
。
//感谢黄小U饮品完善题意
输入格式
三个数, A , B , C A,B,C A,B,C。
输出格式
若干行,每行 3 3 3 个数字。按照每行第一个数字升序排列。
样例 #1
样例输入 #1
1 2 3
样例输出 #1
192 384 576
219 438 657
273 546 819
327 654 981
提示
保证 A < B < C A<B<C A<B<C。
upd 2022.8.3 \text{upd 2022.8.3} upd 2022.8.3:新增加二组 Hack 数据。
二、错误解法
我一开始看到这个题目是准备用暴力解法的:如下很明显会超时
#include <iostream>
using namespace std;
int maxApp(int num1,int num2)
{
for (int i = min(num1,num2); i > 0; i--)
{
if (num1%i==0 && num2%i==0)
{
return i;
}
}
return 1;
}
int main()
{
int a,b,c;
cin>>a>>b>>c;
bool alpha=false;
for (int i = 1; i <= 9; i++)
{
for (int j = 1; j <= 9; j++)
{
for (int k = 1; k <= 9; k++)
{
if (i!=j && j!=k && i!=k)
{
for (int d = 1; d <= 9; d++)
{
for (int e = 1; e <= 9; e++)
{
for (int f = 1; f <= 9; f++)
{
if (d!=e && d!=f && e!=f &&
d!=i && d!=j && d!=k &&
e!=i && e!=j && e!=k &&
f!=i && f!=j && f!=k)
{
for (int x = 1; x <= 9; x++)
{
for (int y = 1; y <= 9; y++)
{
for (int z = 1; z <= 9; z++)
{
if (x!=y && y!=z && x!=z &&
x!=i && x!=j && x!=k &&
y!=i && y!=j && y!=k &&
z!=i && z!=j && z!=k &&
x!=d && x!=e && x!=f &&
y!=d && y!=e && y!=f &&
z!=d && z!=e && z!=f)
{
int num1=100*i+10*j+k;
int num2=100*d+10*e+f;
int num3=100*x+10*y+z;
int app1=maxApp(num1,num2);
int app2=maxApp(num2,num3);
int app3=maxApp(a,b);
int app4=maxApp(b,c);
if (num1/app1==a/app3 && num2/app1==b/app3 &&
num2/app2==b/app4 && num3/app2==c/app4)
{
alpha=true;
cout<<num1<<" "<<num2<<" "<<num3<<endl;
}
}
}
}
}
}
}
}
}
}
}
}
}
if (!alpha)
{
cout<<"No!!!";
}
}
三、正确解法
#include <iostream>
using namespace std;
int main()
{
int k1,k2,k3,a[10]={0},sum=0;
bool alpha=false;
cin>>k1>>k2>>k3;
for (int i = 1; i <= 1000/k3; i++)
{
int b1=i*k1;
int b2=i*k2;
int b3=i*k3;
//检查是否重复
while (b1>0)
{
a[b1%10]++;
b1/=10;
}
while (b2>0)
{
a[b2%10]++;
b2/=10;
}
while (b3>0)
{
a[b3%10]++;
b3/=10;
}
for (int j = 1; j <= 9; j++)
{
if (a[j]!=1)
{
alpha=true;
break;
}
}
//如果含有重复元素或者没用到1~9当中的任何一个,都应该不执行,由于上面的break只退出了最内层循环,因此此处需重置alpha
if (alpha)
{
alpha=false;
}
else
{
sum++;
cout<<i*k1<<" "<<i*k2<<" "<<i*k3<<endl;
}
//重置数组清零
for (int j = 1; j <= 9; j++)
{
a[j]=0;
}
}
if (sum==0)
{
cout<<"No!!!";
}
}