数字谜1 C实现


 

该问题出自《C语言名题精选百则技巧篇》

在一些游戏与休闲的书中,经常看到如下的字谜:

              VINGT

                CINQ

        +      CINQ

           TRENTE

写一个程序进行破解。

说明:

数字谜的规则是这样 的:

(1)不同的英文字母表示不同的数字,因此,题目中最左一行的TQE就是不同的数。

(2)每一个数最左边一位不是0,所以上面的谜题里,V、C、T都不是0.

(3)上面的题目是加,那就表示VINGT这个五位数与CINQ这个四位数的两倍相加后,会得到THRNTE这个六位数,并且数字的安排如谜语所示。

很多人会采用如下的形式

for (V=1;V<=9;V++)
    for(I=0;I<=9;I++)
       ......
           for(E=0;E<=9;E++){
              VINGT = ....;
              CINQ = ...;
              THENTE = ...;
              if(THENTE = VINGT+CINQ+CINQ){
                ......
               }
            }

这样做的耗时很长,我们可以先对这个谜进行分析来缩小字母所代表的数字的范围,范围越小,工作就越少,执行起来就越快。

(1)TRENTE 的最高位数T是(V+千进位)的进位,因为两位数相加,进位最大为1,T为0或者1,因为数字谜规则的(2)规定T不能为0,因此T=1

           结论:T=1

(2)R为(V+千进位)所得两位数的个位数,千进位为三个数相加的进位,三个数相加的最大值为9+9+9=27,因此,最大进位为2,因此R的最大值为(V+2)%10,V最大为           9,因此,R最大值为(9+2)%10 = 1,R值为0或者1,因为T=1,因此R不能再等于1,R=0。

          结论:R=0

(3)在(2)的基础上反推回去,(V+千进位)%10 = 0,V最大为9,千进位为1或者2,则推出V的值为8或者9.

           结论:V=8或者9,也可以表示成8<=V<=9

(4)个位数相加(T+2*Q) = 个进位*10+E,T=1,2*Q为偶数,偶数和奇数的和为奇数,因此E为奇数,因为E不能为1,因此E为3,5,7,9

         结论:E可能为3,5,7,9。

(5)十位数相加(G+2*N+个进位)=T+十进位*10,T=1,N不等于0,因此十进位不能等于0,十进位为1或者2。

            百位数相加(N+2*I+十进位)=N+百进位*10,得出2*I+十进位 = 百进位*10,I不等于0,因此百进位不等于0,百进位为1或者2,百进位*10为偶数,2*I为偶数,因此十进             位为偶数,因此十进位为2

           十进位为2,百进位为1或者2.

          假设十进位为2,百进位为1------2*I+2 = 1*10,I=4

          假设十进位为2,百进位为2------2*I+2 = 2*10,I=9

          结论I = 4或者I=9

(6)千位数相加,(I+2*C+百进位) = E+千进位*10.

            假设百进位为2,即I=9,  如果I=9,   又因为V为8或者9,V不等于I,因此,V=8. V=8,则千进位=2

                                                                            因为E为3,5,7,9,E不等于I,E为3,5,7,E+千进位*10>=23

                                           9+2*C+2>=23, 则C>=6,因为8和9已经被V和I占用了,因此C=6或者7.

                           假设C = 6,则E =3,看个位数相加(T+2*Q) = 个进位+E---->(1+2*Q) = 个进位*10+3.

                                         如果个进位=1,则Q=6---->和C冲突,不成立;

                                         如果个进位=2,则Q=11----->大于9不成立;

                                         C=6,假设不成立;

                            假设C=7,则E = 5,看个位数相加(T+2*Q) = 个进位+E---->(1+2*Q) = 个进位*10+5.

                                           如果个进位=1,则Q=7,---->和C冲突,不成立;

                                           如果个进位=2,则Q=12>10,不成立;

                            假设百进位为2,即I=9的情况下,C的两个可能值都不成立,因此,百进位假设为2不成立,因此I不等于9,因此,I=4

            结论:I=4.百进位为1.

(7)假设V =8,则千进位为2,因为百进位为1,看千位数相加(I+2*C+百进位)=千进位*10+E------>(4+2*C+1)=20+E>=23----->C>=9,则C=9

                            则E=3,看个位数相加(T+2*Q)=E+个进位*10----->(1+2*Q) = 3+个进位*10.;

                                            假设个进位=2,(1+2*Q)>23  ,不成立,因此个进位为0或者1;

                                            假设个进位=0,(1+2*Q)=3,Q=1,和T冲突,不成立,个进位为1;

                                            1+2*Q = 13,---->Q=6;

                                                         个进位为1,看十位数相加(G+2*N+个进位)=十进位*10+T----->(G+2*N+1)=21------>G+2*N = 20,G为偶数,G<=8,N>=6;

                                                                    8和9已经被V和C占据,假设N=6,则G=8和V冲突,不成立;

                                                                                                              假设N=7,则G=6和Q=6冲突,不成立;

                                                         个进位为1的假设也不成立,----->E=3假设不成立----->C=9假设不成立----->V=8假设不成立 ;

           结论V=9.千进位为1,E范围缩小为3,5,7.

(8)  看千位数相加(4+2*C+百进位)=千进位*10+E------>(4+2*C+1)=10+E;

                                    假设E=3.则C=4,和I冲突,不成立;

                                    假设E=5,则C=5,和E冲突,不成立;

                                    假设E=7,则C=6无冲突,成立;

           结论:E=7;C=6

(9)看个位数相加(1+2*Q) = E+个进位*10,---->(1+2*Q) = 7+个进位*10;个进位为0或者1

           假设个进位为1,则Q=8;看十位数相加(G+2*N+1)= 21----->G+2*N=20.

            现在可用的数只有2,3,5,8,G为偶数,

                            假设G为2,则N=9和V冲突不成立;

                             假设G为8,则N=6和C冲突,不成立;

                              假设个进位为1不成立,个进位为0

            个进位为0,则Q=3 

            结论:Q=3

(10)现在可用的数只有2,5,8。看十位相加(G+2*N+个进位)=T+十进位*10----->(G+2*N+个进位) = 21---->G+2*N=21

              很容易可以看出来,G=5,N=8.

总结,

                  V I N G T                                     9 4 8 5 1

                    C I N Q                                         6 4 8 3

     +            C I N Q                                +       6 4 8 3                           

            T R E N T E                                   1 0 7 8 1 7 

我们可以在以上步骤的任意一个步骤开始编程,以下编程是在第(5)步结束的基础上开始编程。

#include <stdio.h>
#include <stdlib.h>

int main(int argc,char *argv[])
{
	int V,I,N,G,T=1,C,Q,R=0,E;
	long IN,VINGT,CINQ,TRENTE;
	long sum;
	
	printf("\nNumber Puzzle\n");
	printf("\n    VINGT");
	printf("\n     CINQ");
	printf("\n+)   CINQ");
	printf("\n---------");
	printf("\n   TRENTE\n");
	
	for(V=8;V<=9;V++)
		for(I=4;I<=9;I=I+5)
		    if(I!=V&&I!=T)
		        for(N=2;N<=9;N++)
		            if(N!=I&&N!=V){
		                IN = 10*I+N;
		                for(G=2;G<=9;G++)
		                    if(G!=N&&G!=I&&G!=V)
		                        for(C=2;C<=9;C++)
		                            if(C!=G&&C!=N&&C!=I&&C!=V)
		                                for(Q=2;Q<=9;Q++)
		                                    if(Q!=C&&Q!=G&&Q!=N&&Q!=I&&Q!=V)
		                                        for(E=3;E<=9;E++)
		                                            if(E!=Q&&E!=C&&E!=N&&E!=I&&E!=Q){
								TRENTE = ((((T*10+R)*10+E)*10+N)*10+T)*10+E;
								VINGT = ((V*100+IN)*10+G)*10+T;
								CINQ = (C*100+IN)*10+Q;
								sum = VINGT+CINQ+CINQ;
								if(sum == TRENTE){
								    printf("\n\nThe answer is:\n");
								    printf("\n%8ld",VINGT);
								    printf("\n%8ld",CINQ);
								    printf("\n+)%6ld",CINQ);
								    printf("\n--------");
								    printf("\n%8ld",TRENTE);
							        }
							    }
														     
														
		                                                
			}
	getchar();
	return 0;
} 
如果是在第(6)步基础上编程,可以将

for(I=4;I<=9;I=I+5)
    if(I!=V&&I!=T)
注释掉,在
int V,I,N,G,T=1,C,Q,R=0,E;
改为

int V,I=4,N,G,T=1,C,Q,R=0,E;
在(7)(8)(9)基础上的编程不再赘述。

运行结果



                                                                                                                                          

            

            

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值