题目描述
将1,2, ⋯,9共9个数分成3组,分别组成3个三位数,且使这3个三位数构成1:2:3的比例,试求出所有满足条件的3个三位数。
输入输出格式
输入格式:
木有输入输出格式:
若干行,每行3个数字。按照每行第1个数字升序排列。
输入输出样例
输入样例#1:
无
输出样例#1:
192 384 576
… (输出被和谐了)分析:
题意为输出3个三位数,如何将所有的三位数罗列出来?只用一个for循环生成三个排列的数不简单,可以考虑使用三个for循环,按照百位、十位、个位拼接成三位数。仅仅得到一个三位数如何找到另外两个三位数呢?题意说明1-9各用一次,正面求解不方便可以直接将得到的三位数乘以2,乘以3,判断是否9个数字全部用上
int main() { for (int i = 1; i <= 9; ++i) { for (int j = 0; j <= 9; ++j) { for (int k = 0; k <= 9 ; ++k) { int a = i*100+j*10+k; int b = a*2; int c = a*3; if(b>999||c>999)continue; nums[i]=1; nums[j]=1; nums[k]=1; nums[b/100]=1; nums[(b/10)%10]=1; nums[b%10]=1; nums[c/100]=1; nums[(c/10)%10]=1; nums[c%10]=1; if(nums[1]==1&&nums[2]==1&&nums[3]==1&&nums[4]==1&&nums[5]==1&&nums[6]==1&&nums[7]==1&&nums[8]==1&&nums[9]==1) printf("%d %d %d \n",a,b,c); for (int l = 0; l < 10; ++l) { nums[l] = 0; } } } } return 0;}
简单优化:
void sanlie(int no){ while (no!=0){ nums[no%10]=1;//取最后一位,做散列查表 no/=10;//消除最后一位 }}int main() { for (int i = 1; i <= 9; ++i) { for (int j = 0; j <= 9; ++j) { for (int k = 0; k <= 9 ; ++k) { int a = i*100+j*10+k; int b = a*2; int c = a*3; if(b>999||c>999)continue; sanlie(a); sanlie(b); sanlie(c); if(nums[1]==1&&nums[2]==1&&nums[3]==1&&nums[4]==1&&nums[5]==1&&nums[6]==1&&nums[7]==1&&nums[8]==1&&nums[9]==1) printf("%d %d %d \n",a,b,c); memset(nums,0, sizeof(nums)); } } } return 0;}
学到的点:
1、使用百位+十位+个位的方式构造数值 2、使用memset()重置数组,比for循环高效 3、使用数值中出现的数字作为数组的下标,表示是否出现(散列法、查表法),第一次的想法为利用数组存放三个三位数出现的数字,下标为自然0-9,需要比较各不相同(1,2…9),相比散列只需比较是否出现(为1) 4、求数组长度sizeof(nums)/ sizeof(nums[0])
,sizeof求得是字节长度(下面的例子) 不太懂循环怎么写,于是尝试了下:
void xunhuan() { for (int i = 1; i < 10; ++i) { for (int j = 1; j < 10; ++j) { for (int k = 1; k < 10; ++k) { for (int l = 1; l < 10; ++l) { for (int m = 1; m < 10; ++m) { for (int n = 1; n < 10; ++n) { for (int i1 = 1; i1 < 10; ++i1) { for (int j1 = 1; j1 < 10; ++j1) { for (int k1 = 1; k1 < 10; ++k1) { int a = i * 100 + j * 10 + k; int b = l * 100 + m * 10 + n; int c = i1 * 100 + j1 * 10 + k1; int nums[10] ={ i,j,k,l,m,n,i1,j1,k1}; int flag = 1; for (int l1 = 0; l1 < sizeof(nums)/ sizeof(nums[0]); ++l1) { for (int m1 = l1+1; m1 < sizeof(nums)/ sizeof(nums[0]); ++m1) { if(nums[m1]==nums[l1]) { flag=0; break; } } if(flag == 0)break; } if (a * 2 == b && a * 3 == c && b < 1000 && c < 1000&&flag) { printf("%d %d %d \n", a, b, c); } } } } } } } } } }}