第一部分:題目
方格填數
如下的10個格子
+--+--+--+
| | | |
+--+--+--+--+
| | | | |
+--+--+--+--+
| | | |
+--+--+--+
(如果顯示有問題,也可以參看下圖)
填入0~9的數字。要求:連續的兩個數字不能相鄰。
(左右、上下、對角都算相鄰)
一共有多少種可能的填數方案?
請填寫表示方案數目的整數。
注意:你提交的應該是一個整數,不要填寫任何多余的內容或說明性文字。
第二部分:思路
這個題目有點表述不明,不知道0~9 可不可以重復使用。現在看來是不能重復使用的。
我的做法是把表格當做3行4列的數組,去掉一頭一尾。
步驟:填數字->判斷是否滿足要求:相鄰位置數字不能相鄰。
需要注意的地方:保證數字沒有重復使用:借助數組take,存儲使用的數字,當所要填寫的數字不在數組中時才可以填入。填入后存進數組。
判斷是否滿足相鄰位置數字不能相鄰的要求。看代碼注釋。
答案是:
1580
第三部分:代碼
#include<stdio.h> #include<stdlib.h> int count=0; int take[10],index=0;//記錄當前已經填入的數字,用於填數字前判斷是否已經使用,避免重復使用 int is_legal(int s[3][4])//判斷是否滿足要求:相鄰位置數字不能相鄰,就是兩數字的差大於1.就是為什么s[0][0]、s[2][3]置為-2; { //這里的判斷方法有點死板。假設每個位置都有上下左右和對角,只需要判斷這些位置 //是不是在數組中,在就進行比較,不在就說明沒有。 for(int i=0;i<3;i++) { for(int j=0;j<4;j++) { if(j-1>=0) { if(abs(s[i][j]-s[i][j-1])==1) { return 0; } } if(j+1<4) { if(abs(s[i][j]-s[i][j+1])==1) { return 0; } } if(i+1<3) { if(abs(s[i][j]-s[i+1][j])==1) { return 0; } } if(j-1>=0&&i+1<3) { if(abs(s[i][j]-s[i+1][j-1])==1) { return 0; } } if(j+1<4&&i+1<3) { if(abs(s[i][j]-s[i+1][j+1])==1) { return 0; } } if(i-1>=0&&j+1<4) { if(abs(s[i][j]-s[i-1][j+1])==1) { return 0; } } if(i-1>=0) { if(abs(s[i][j]-s[i-1][j])==1) { return 0; } } if(j-1>=0&&i-1>=0) { if(abs(s[i][j]-s[i-1][j-1])==1) { return 0; } } } } return 1; } void fun(int s[3][4],int a,int b) { int i; if(a==2&&b==3)//表示當前已經填滿了表格,需要進行判斷看是否滿足要求 { if(is_legal(s)) { count++; } } else//繼續填寫 { for(i=0;i<=9;i++) { int j; for(j=0;j<index;j++)//填寫的數字必須是沒有用過的 { if(i==take[j]) { break; } } if(j==index) { s[a][b]=i; take[index++]=i; if(b<3)//表示當前行還沒填完 { fun(s,a,b+1); } else//當前行填完就從下一行開始 { if(a<2)//判斷當前行是否是最后一行 { fun(s,a+1,0); } } index--;//在一次填滿結束后,當前位置的數字換為其他可以填寫的數字 //所以當前使用的數字需要出去。 } } } } int main() { int s[3][4]; s[0][0]=-2; s[2][3]=-2; //左上角和右下角沒有,為了方便判斷把數值設為-2(小於-1大於10均可) fun(s,0,1); printf("%d\n",count); return 0; }