问题:将1,2,⋯,9共9个数分成3组,分别组成3个三位数,且使这3个三位数构成1:2:3的比例,试求出所有满足条件的3个三位数。
关于三连击,这是一道对新手而言不友好的题目,但是因为测试范围不是很大,我们可以直接考虑暴力解法,在1、2、3、4、5、6、7、8、9中三个一组,先看是否为1:2:3的关系,若成立,我们在利用bool数组去判断是否全部的数都出现了(也就是没有重复利用某个数),二话不说上代码!(应该最简单粗暴好理解了吧)
#include <iostream>
#include<bits/stdc++.h>//万能头文件不多BB
using namespace std;
bool a[10];
int main()
{
int n,k,l,x1,x2,x3,y1,y2,y3,z1,z2,z3;
for(n=123;n<987;n++)//1-9最小是123,最大是987
{
for(k=123;k<987;k++)
{
for(l=123;l<987;l++)
{
if(k==2*n&&l==3*n)//判断是否成立(显示问题??判断k=2n且l=3n是否成立)
{
int flag=0;
memset(a,false,sizeof(a));//初始化数组为假
x1=n/100;//这个不用多说了吧,把一个三位数拆成三个数
y1=n/10%10;
z1=n%10;
x2=k/100;
y2=k/10%10;
z2=k%10;
x3=l/100;
y3=l/10%10;
z3=l%10;
a[x1]=true;//出现了哪个数,bool数组就记为真
a[x2]=true;
a[x3]=true;
a[y1]=true;
a[y2]=true;
a[y3]=true;
a[z1]=true;
a[z2]=true;
a[z3]=true;
for(int i=1;i<=9;i++)
{
if(!a[i])//只要有一个bool不为真,那么改flag
{
flag=1;
}
}
if(!flag)printf("%d %d %d\n",n,k,l);//如果非flag是真,那么flag没有被改(在判断里,不是0即为真),即所有数字都出现,则输出
}
}
}
}
return 0;
}
但是很不幸,因为用了三个for循环,时间复杂度较高,就TLE了......(time limited exceeded),上一个用例时间是1092ms,这就很尴尬。 好了,既然就超限了一点,那么我们完全可以稍微改一点就成,根据我们的测试结果,可以知道,最小的满足题解数是192,最大是981,于是我们稍加改动,就可以满足时间<1000ms,改后大概700ms??(我忘了),上代码!
#include <iostream>
#include<bits/stdc++.h>
using namespace std;
bool a[10];
int main()
{
int n,k,l,x1,x2,x3,y1,y2,y3,z1,z2,z3;
for(n=192;n<982;n++)
{
for(k=192;k<982;k++)
{
for(l=192;l<982;l++)
{
if(k==2*n&&l==3*n)//(同上,判断k=2n和l=3n是否成立)
{
int flag=0;
memset(a,false,sizeof(a));
x1=n/100;
y1=n/10%10;
z1=n%10;
x2=k/100;
y2=k/10%10;
z2=k%10;
x3=l/100;
y3=l/10%10;
z3=l%10;
a[x1]=true;
a[x2]=true;
a[x3]=true;
a[y1]=true;
a[y2]=true;
a[y3]=true;
a[z1]=true;
a[z2]=true;
a[z3]=true;
for(int i=1;i<=9;i++)
{
if(!a[i])
{
flag=1;
}
}
if(!flag)printf("%d %d %d\n",n,k,l);
}
}
}
}
return 0;
}
编者钟爱暴力解法,若小伙伴们觉得好理解的话,望支持!!