一、题目
将1-9这9个数字组合成3个三位数,要求第2个三位数是第一个三位数的2倍,第3个三位数是第一个三位数的3倍。找出所有的可能方案。
二、求解
如果直接求出所有符合要求的排列组合的数那效率会特别低,所以最基本的思路就是先用便捷的方法得到满足一部分要求的数,再筛选。
Method 1:暴力求解
组合的三位数的范围是111-999(重复的、含0的最后排除)
那么第一个数的范围就是111-333
遍历111-333,求出三个数字的每一位数字
排除掉含重复数组和含数字0的方案
程序:
%% method1: 遍历法
for i=123:333 % 第一个数的范围
check(i);
end
function check( data1 )
%CHECK 此处显示有关此函数的摘要
% 此处显示详细说明
a=zeros(1,9); % 提取9个数据
% 第一个数字i
a(1)=mod(data1,10); % 取余数,个位
a(2)=mod(floor(data1/10),10); % 十位
a(3)=mod(floor(data1/100),10);% 百位
% 第二个数字2*i
a(4)=mod(2*data1,10);
a(5)=mod(floor(2*data1/10),10);
a(6)=mod(floor(2*data1/100),10);
% 第三个数字3*i
a(7)=mod(3*data1,10);
a(8)=mod(floor(3*data1/10),10);
a(9)=mod(floor(3*data1/100),10);
% 排列组合
for i=1:8 % 九个数据两两对比
for j = (i + 1):9
if (a(i) == a(j)||a(i)==0||a(j)==0) % 如果存在相等或者为0的数据,则退出
break;
end
end;
if (j < 9) % 循环结束
break;
end
end
% 打印输出
if i == 8 && j == 9 % 全部遍历结束则表示数据符合要求
fprintf('方法1符合条件数据: a=%d,b=%d,c=%d\n', data1, data1*2, data1*3);
end
Method 2:排列组合
第二个方法参考了别人的。借助一个110的初值为0数组。
还是提取3个三位数的每一位,并在这个数的标号下置1,代表这个数字出现过。
如果每一个数组都出现过,那么这个110的数组就有9个1,1个0。
通过求和,数组元素之和等于9,则表示9个数字各不相同。
同时需要排除数字为0的情况。
程序:
%% method2: 格子填充
for i=123:329
a=zeros(1,10); % 1*10的数组格子
% 第一个数
a(mod(i,10)+1)=1; % 个位, 该序号位置填充为1
a(mod(floor(i/10),10)+1)=1; % 十位
a(mod(floor(i/100),10)+1)=1;% 百位
j=i*2;
a(mod(j,10)+1)=1;
a(mod(floor(j/10),10)+1)=1;
a(mod(floor(j/100),10)+1)=1;
k=i*3;
a(mod(k,10)+1)=1;
a(mod(floor(k/10),10)+1)=1;
a(mod(floor(k/100),10)+1)=1;
s=sum(a); % 十个数求和
if(s==9 && a(1)~=1) % s==9的话表示有9个不同的数字,a(1)==1等价于数字0
fprintf('方法2符合条件数据: a=%d,b=%d,c=%d\n', i, j,k);
end
end