從暴力列舉到深度優先搜尋
阿新 • • 發佈:2019-01-07
題目描述:
+=
將數字1~9分別填入9個中,每個數字只能使用一次使得等式成立。
例如173+286=459 就是一個合理的組合,請問一共有多少組合呢?
注意:173+286=459 與 286+173=459 是同一種組合!
暴力列舉:
列舉每一位上所有的可能,判斷等式是否成立就好了:
#include <stdio.h> int main(){ int a,b,c,d,e,f,g,h,i,total=0; for(a=1;a<=9;a++) for(b=1;b<=9;b++) for(c=1;c<=9;c++) for(d=1;d<=9;d++) for(e=1;e<=9;e++) for(f=1;f<=9;f++) for(g=1;g<=9;g++) for(h=1;h<=9;h++) for(i=1;i<=9;i++) {//接下來要判斷每一位上的數互不相等 if(a!=b && a!=c && a!=d && a!=e && a!=f && a!=g && a!=h && a!=i && b!=c && b!=d && b!=e && b!=f && b!=g && b!=h && b!=i && c!=d && c!=e && c!=f && c!=g && c!=h && c!=i && d!=e && d!=f && d!=g && d!=h && d!=i && e!=f && e!=g && e!=h && e!=i && f!=g && f!=h && f!=i && g!=h && g!=i && h!=i && a*100+b*10+c+d*100+e*10+f==g*100+h*10+i) { total++; printf("%d%d%d+%d%d%d=%d%d%d\n",a,b,c,d,e,f,g,h,i); } } printf("total=%d",total/2); getchar();getchar(); return 0; }
判斷9個數互不相等的部分,可使用一個book標記陣列使程式碼更簡潔:
#include <stdio.h> int main(){ int a[10],i,total=0,book[10],sum; for(a[1]=1;a[1]<=9;a[1]++) for(a[2]=1;a[2]<=9;a[2]++) for(a[3]=1;a[3]<=9;a[3]++) for(a[4]=1;a[4]<=9;a[4]++) for(a[5]=1;a[5]<=9;a[5]++) for(a[6]=1;a[6]<=9;a[6]++) for(a[7]=1;a[7]<=9;a[7]++) for(a[8]=1;a[8]<=9;a[8]++) for(a[9]=1;a[9]<=9;a[9]++) { //初始化book陣列 for (i=1; i<=9; i++) book[i]=0; for(i=1;i<=9;i++) book[a[i]]=1; //統計共出現了多少個不同的數 sum=0; for (i=1; i<=9; i++) sum+=book[i]; //如果剛好出現了9個不同的數,並且滿足等式,則輸出 if (sum == 9 && a[1]*100+a[2]*10+a[3]+a[4]*100+a[5]*10+a[6]==a[7]*100+a[8]*10+a[9]) { total++; printf("%d%d%d+%d%d%d=%d%d%d\n",a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9]); } } printf("total=%d",total/2); getchar();getchar(); return 0; }
深度優先搜尋:
依次將1~9分別填入9個中,判斷等式是否成立,重點在於如何不重複填入,見註釋:
#include <stdio.h> int a[10],book[10],total=0; //a陣列為方框,即在a[1]-a[9]中分別填入9個數,使得等式成立,book為標記陣列 void dfs(int step)//step表示當前需要填的是哪一個框 { if(step == 10)//當9個框都填滿時,判斷等式是否成立 { if((a[1]*100+a[2]*10+a[3]+a[4]*100+a[5]*10+a[6]) == (a[7]*100+a[8]*10+a[9])) { total++; printf("%d%d%d + %d%d%d = %d%d%d\n",a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9]); } return; } for (int i=1; i<=9; i++) { //如果i沒有被填進框 if (book[i] == 0) { a[step] = i;//把i填入當前的框 book[i] = 1;//標記i已經被填入 dfs(step+1);//去填下一個框 book[i] = 0;//每填完9個框,標記陣列重新清零 } } return; } int main(){ dfs(1); printf("total=%d",total/2);//每個式子都算了兩次,所以除以2 getchar();getchar(); return 0; }
注:本題來自《啊哈!演算法》