[NOIP1998 普及组] 三连击

题目背景

本题为提交答案题,您可以写程序或手算在本机上算出答案后,直接提交答案文本,也可提交答案生成程序。

题目描述

将 $1, 2, \ldots , 9$ 共 $9$ 个数分成 $3$ 组,分别组成 $3$ 个三位数,且使这 $3$ 个三位数构成 $1 : 2 : 3$ 的比例,试求出所有满足条件的 $3$ 个三位数。

输入格式

输出格式

若干行,每行 $3$ 个数字。按照每行第 $1$ 个数字升序排列。

样例 #1

样例输入 #1

1

样例输出 #1

1
2
3
4
5
6
192 384 576
* * *
...

* * *
(剩余部分不予展示)

主要思路

1.将数的每一位用数组储存
2.比较数组间的数字是否有重复或者是0的情况

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
int same(int x,int y)
{
int a[3];
int b[3];
int i,j,num=1;
for(i=0;i<=2;i++){
a[i]=x%10;
x=x/10;
b[i]=y%10;
y=y/10;
}
for(i=0;i<=2;i++){
for(j=0;j<=2;j++){
if((a[i]==b[j])||(a[i]==0)||(b[j]==0)){
num=0;
break;
}
}
if(num==0){
break;
}
}
if(num==1){
for(i=0;i<=2;i++){
for(j=i+1;j<=2;j++){ //从第i+1开始,防止重复比较
if(a[i]==a[j]||b[i]==b[j]){
num=0;
break;
}
}
if(num==0){
break;
}
}
}
return num;
}

易错点

没有进行自身数字相等的检查,导致222,444,666此类数的出现

完整代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <stdio.h>
int same(int x,int y);
int main()
{
int a,b,c;
for(a=192;a<333;a++)
{
b=a*2;
c=a*3;
if(same(a,b)==1&&same(a,c)==1&&same(b,c)==1){
printf("%d %d %d\n",a,b,c);
}
}
return 0;
}
int same(int x,int y)
{
int a[3];
int b[3];
int i,j,num=1;
for(i=0;i<=2;i++){
a[i]=x%10;
x=x/10;
b[i]=y%10;
y=y/10;
}
for(i=0;i<=2;i++){
for(j=0;j<=2;j++){
if((a[i]==b[j])||(a[i]==0)||(b[j]==0)){
num=0;
break;
}
}
if(num==0){
break;
}
}
if(num==1){
for(i=0;i<=2;i++){
for(j=i+1;j<=2;j++){
if(a[i]==a[j]||b[i]==b[j]){
num=0;
break;
}
}
if(num==0){
break;
}
}
}
return num;
}

优化筛选

只需判断九个数相加是否为1+2+3+4+5+6+7+8+9并且九个数相乘是否为9!即可

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>
int main()
{
int a,b,c;
for(a=123;a<=333;a++)
{
b=a*2;
c=a*3;
if((a/100+a/10%10+a%10+b/100+b/10%10+b%10+c/100+c/10%10+c%10==1+2+3+4+5+6+7+8+9)&&((a/100)*(a/10%10)*(a%10)*(b/100)*(b/10%10)*(b%10)*(c/100)*(c/10%10)*(c%10)==(1)*(2)*(3)*(4)*(5)*(6)*(7)*(8)*(9)))
printf("%d %d %d\n",a,b,c);
}
return 0;
}