1. 程式人生 > >題解:猜數字——窮舉法的應用

題解:猜數字——窮舉法的應用

【題目】在下面的加法算式中,不同的符號代表不同的數字,相同的符號代表相同的數字。請設計程式求出"都、要、學、C"4個符號分別代表的數字。

          學  C
      要  學  C
+ 都  要  學  C
________________
  2   0   0   8

【本講結構】

(一)講解視訊

(二)相關習題

(三)視訊中的程式碼

(四)其他寫法的程式碼

(五)部分相關習題的參考例程

【正文】

(一)講解視訊(點下面的圖示,視訊中有個口誤,“列舉”應該為“窮舉”。)


(二)相關習題

1. (程式設計題)下列乘法算式中:每個漢字代表1個數字(1~9)。相同的漢字代表相同的數字,不同的漢字代表不同的數字。試程式設計確定使得整個算式成立的數字組合,如有多種情況,請給出所有可能的答案。

       賽軟體
     ×   比賽
   ----------
   =  軟體比拼

(*)2. 兩個乒乓球隊進行比賽,各出三人。甲隊為a,b,c三人,乙隊為x,y,z三人。已抽籤決定比賽名單。有人向隊員打聽比賽的名單。a說他不和x比,c說他不和x,z比,請程式設計序找出三對賽手的名單。(提示:此題貌似與猜數字無關,但有相同的思路。無非是a有可能與x,y,z中的任一個打,b、c也是這樣。構造迴圈,窮舉之。)

3. 有等式[※×(※3+※)]2=8※※9,其中※處為1個數字,滴上了墨水無法辨認。請程式設計找出※表示哪個數字。

4. 在下列加法的算式中,A、B、C、D、E、F、G、H、M、N分別表示0-9的不同數字,且A、D、M不為0,程式設計求出這些數字並且輸出這些數字組成的算術計算豎式。

     A  B  C  D  E
           D  F  G
+          D  F  G
--------------------

     M  N  H  D  E    

  (提示:此題用窮舉的辦法自然可以,但7重迴圈加上各種判斷,太繁雜了。參考《狂人C——程式設計師入門必備》P348,用回溯法解決。開始學一些演算法策略應該的。

(三)視訊中的程式碼

未優化前的程式碼

#include <iostream>  
using namespace std;  
int main()  
{ 
	int dou,yao,xue,c,s;//變數這樣取,比有些題解上用i,j,p,q之類的要清晰得多
	for(dou=1;dou<3;dou++)
		for(yao=0;yao<10;yao++)
			for(xue=0;xue<10;xue++)
				for(c=0;c<10;c++)
					if((dou-yao)*(dou-xue)*(dou-c)*(yao-xue)*(yao-c)*(xue-c)!=0)//一個技巧:表示兩兩不同可以這樣做
					{
						s=4*c+3*xue*10+2*yao*100+dou*1000;
						if(2008==s) 
							cout<<dou<<yao<<xue<<c<<endl;
					}
		return 0;
}  

最終的求解程式

#include <iostream>  
using namespace std;  
int main()  
{ 
	int dou,yao,xue,c,s;
	for(dou=1;dou<3;dou++)
		for(yao=0;yao<10;yao++)
		{
			if(dou==yao) continue;//“都”和“要”的取值如果相同了,將不再考慮另外兩字的取值,效果可觀
			for(xue=0;xue<10;xue++)
			{
				if(xue==yao||xue==dou) continue;  //理由同上
				for(c=0;c<10;c++)
					if((dou-c)*(yao-c)*(xue-c)!=0)
					{
						s=4*c+3*xue*10+2*yao*100+dou*1000;
						if(2008==s) 
							cout<<dou<<yao<<xue<<c<<endl;
					}
			}
		}
		return 0;
}  


(五)部分相關習題的參考例程

(*)2. 兩個乒乓球隊進行比賽,各出三人。甲隊為a,b,c三人,乙隊為x,y,z三人。已抽籤決定比賽名單。有人向隊員打聽比賽的名單。a說他不和x比,c說他不和x,z比,請程式設計序找出三對賽手的名單。(提示:此題貌似與猜數字無關,但有相同的思路。無非是a有可能與x,y,z中的任一個打,b、c也是這樣。構造迴圈,窮舉之。)

#include <iostream>  
using namespace std;  
int main()  
{ 
	char a_pk,b_pk,c_pk;   //a_pk是a的對手,b_pk是b的對手,c_pk是c的對手 
	for(a_pk='x';a_pk<='z';a_pk++)
		for(b_pk='x';b_pk<='z';b_pk++)
		{
			if(a_pk!=b_pk)
				for(c_pk='x';c_pk<='z';c_pk++)
				{ 
					if(a_pk!=c_pk&&b_pk!=c_pk)
					{ 
						if(a_pk!='x'&&c_pk!='x'&&c_pk!='z')
							printf("order is a--%c\tb--%c\tc--%c\n",a_pk,b_pk,c_pk);
					}
				}
		}
		return 0;
}