题目描述
将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
",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
",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
", a, b, c);
}
}
}
}
}
}
}
}
}
}
}