[NOIP1998 普及组] 三连击
题目背景
本题为提交答案题,您可以写程序或手算在本机上算出答案后,直接提交答案文本,也可提交答案生成程序。
题目描述
将 $1, 2, \ldots , 9$ 共 $9$ 个数分成 $3$ 组,分别组成 $3$ 个三位数,且使这 $3$ 个三位数构成 $1 : 2 : 3$ 的比例,试求出所有满足条件的 $3$ 个三位数。
输入格式
无
输出格式
若干行,每行 $3$ 个数字。按照每行第 $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; }
|