一道算法题的求解

一、题目

将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,代表这个数字出现过。
如果每一个数组都出现过,那么这个1
10的数组就有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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值