1

我正在尝试使用 matlab 解决一个谜语。这实际上更多地是关于 matlab,而不是谜语本身(谜语来自日报)。

谜语给出了两个用字母表示的 3 位数字。我需要找到不参与的数字(0-9)。

aba-dcc=efe ; aba+dcc=ghi

现在,我有 2 个方程,有 9 个未知数。我设法通过在一个while循环中检查向量0:9的所有排列来解决它。

vecAns = 0:9;
P = perms(vecAns);
P = P(:,1:9);

A = [ 101 10 -100 -11 -101 -10 0 0 0 ;...
        101 10 100 11 0 0 -100 -10 -1];

resVec = [0;0];
found=false;

i=1;
h = waitbar(0,'Computing');
while found==false
        Res=A*P(i,:)';
        if (Res(1)==0)&&(Res(2)==0)
            break;
        end
        i=i+1;
        waitbar(i/length(P),h,sprintf('%d%%',i/length(P)*100));
end
close(h) 

有没有办法(不增加数学考虑)来解决这个问题。例如,我知道所有未知数必须是整数,并且在 0-9 范围内。

如果没有办法。怎样才能提高效率?

4

1 回答 1

1

您不必枚举所有排列。您可以从前 4 位数字(a、和)开始b,并检查它们是否产生与 和 匹配的差值和总和。您还需要确保所有数字都是不同的。cdefeghi

我对matlab代码的编写不是很熟练,所以我用C#代码来演示一下:

//aba-dcc=efe
//aba+dcc=ghi
for (int a = 1; a <= 9; a++) // 'a' cannot be zero
for (int b = 0; b <= 9; b++)
if (a != b)
for (int c = 0; c <= 9; c++)
if (c != a && c != b)
for (int d = 1; d <= 9; d++) // 'd' cannot be zero
if (d != a && d != b && d != c)
{
    int aba = a*101 + b*10;
    int dcc = c*11 + d*100;

    int efe = aba - dcc;
    if (efe < 0) continue;

    int ghi = aba + dcc;
    if (ghi > 999) continue;

    int e = efe % 10;
    if (e == a || e == b || e == c || e == d) continue;

    int f = (efe/10)%10;
    if (f == a || f == b || f == c || f == d || f == e) continue;

    if (efe != e*101 + f*10) continue;

    int i = ghi%10;
    if (i == a || i == b || i == c || i == d || i == e || i == f) continue;

    int h = (ghi/10)%10;
    if (h == a || h == b || h == c || h == d || h == e || h == f || h == i) continue;

    int g = (ghi/100)%10;
    if (g == a || g == b || g == c || g == d || g == e || g == f || g == i || g == h) continue;

    Console.WriteLine("{0:d3}-{1:d3}={2:d3} ; {0:d3}+{1:d3}={3:d3}", aba, dcc, efe, ghi);
}

这在我的计算机上不到一毫秒就完成了。

输出:

717-233=484 ; 717+233=950

%是模数,/是整数除法。continue跳到循环的下一次迭代。)

于 2013-06-22T15:52:40.947 回答