A B C D E
D F G
+ D F G
---------
X Y Z D E
由式可知( E + G + G ) % 10 = E,意思說(G+G)是10的整數倍。所以,G可能為0,也可能為5。
現在我們考慮G=5的情況,也就是說 E + 2G = 10 + E,所以需要往前面進壹位。那麽就有( D + F + F + 1 ) % 10 = D,也就是說對(D + 2F + 1)求余,還是D,現在設D為奇數,
那麽(D + 2F + 1)就必然為偶數,壹個偶數對10求余,結果必然也是偶數,這跟結果是D(奇數)相沖突。所以,G=5是不成立的。於是只剩下壹種情況,那就是G=0。
現在我們知道G=0,所以就存在等式 ( D + 2F ) % 10 = D,意思說2F也是10的整數倍。由於已經有G=0,所以F=5。
根據前面得出的結論F=5,所以有D + 2F = 10 + D,所以也會往前面進1。那麽就有等式( C + 2D + 1 ) % 10 = Z
根據題意,我們知道不同的字母代表不同的數字。所以 B 和 Y 以及 A 和 X,自然代表不同的數字。由公式我們可以看出,B + ( C + 2D + 1 )/10 = Y + n * 10,這裏的n,代
表向前進位的數。根據各個字母的取值範圍(0,9),我們可以得出結論:
n = 1
A + 1 = X
由於 0 <= ( C + 2D + 1 )/10 <= 2,且 Y >= 1 (因為G=0)
所以有:
B = 9
( C + 2D + 1 )/10 = 2,即 C + 2D + 1 = 20 + Z
綜上,可得A的取值表
_VA[] = { 1, 2, 3, 6, 7 };
同時由於 X = A + 1
所以,X的取值表
_VX[] = { 2, 3, 4, 7, 8 };
那麽除去這五個值之外的取值有就為
_VLEFT[][5] = {
{ 3, 4, 6, 7, 8 },
{ 1, 4, 6, 7, 8 },
{ 1, 2, 6, 7, 8 },
{ 1, 2, 3, 4, 8 },
{ 1, 2, 3, 4, 6 }
}
所以程序代碼為:
unsigned char A, B, C, D, E, F, G, X, Y, Z;
unsigned char _VA[] = { 1, 2, 3, 6, 7 };
unsigned char _VX[] = { 2, 3, 4, 7, 8 };
unsigned char _VLEFT[][5] = {
{ 3, 4, 6, 7, 8 },
{ 1, 4, 6, 7, 8 },
{ 1, 2, 6, 7, 8 },
{ 1, 2, 3, 4, 8 },
{ 1, 2, 3, 4, 6 }
};
G = 0;
F = 5;
B = 9;
unsigned char * pLeft;
bool completed = false;
for( int i = 0; i < 5; i ++ )
{
A = _VA[ i ];
X = _VX[ i ];
pLeft = &_VLEFT[ i ][ 0 ];
//C + 2D + 1 = 20 + Z
for( int j0 = 0; j0 < 5; j0 ++ )
{
C = pLeft[j0];
for( int j1 = 0; j1 < 5; j1 ++ )
{
if( j1 == j0 ) continue;
D = pLeft[j1];
for( int j2 = 0; j2 < 5; j2 ++ )
{
if( j2 == j0 || j2 == j1 ) continue;
Z = pLeft[ j2 ];
if( ( C + 2 * D ) == ( 19 + Z ) )
{
Y = ( ( C + 2 * D + 1 ) / 10 + B ) % 10;
if( Y != A && Y != Z )
{
for( int j3 = 0; j3 < 5; j3 ++ )
{
if( j3 != j0 && j3 != j1 && j3 != j2 && pLeft[ j3 ] != Y )
{
E = pLeft[ j3 ];
}
}
completed = true;
break;
}
}
}
if( completed ) break;
}
if( completed ) break;
}
if( completed ) break;
}
結果是:
2 9 7 8 6
8 5 0
+ 8 5 0
----------
3 1 4 8 6
其中有效循環次數僅為106次。
第二題由如下代碼:
unsigned char A, B, C, D, E;
A = 1;
Retry:
B = A;
C = !B;
D = C;
E = !D;
if( E && ! ( A && D ) )
{
A = 0;
goto Retry;
}
printf_s( "A = %d, B = %d, C = %d, D = %d, E = %d\n",
A, B, C, D, E );
因為A只有兩種可能,去或者不去,所以只需要確定這壹個就可以了,然後按照題意可以推出其它的狀態,然後判斷是不是自相矛盾。如果不矛盾,那麽,就算正確了。
運行結果如下:
A = 0, B = 0, C = 1, D = 1, E = 0
只有C和D去了。