完美正方形(暴力深搜)
阿新 • • 發佈:2019-02-04
標題:完美正方形
如果一些邊長互不相同的正方形,可以恰好拼出一個更大的正方形,則稱其為完美正方形。
歷史上,人們花了很久才找到了若干完美正方形。比如:如下邊長的22個正方形
2 3 4 6 7 8 12 13 14 15 16 17 18 21 22 23 24 26 27 28 50 60
如【圖1.png】那樣組合,就是一種解法。此時,
緊貼上邊沿的是:60 50
緊貼下邊沿的是:26 28 17 21 18
22階完美正方形一共有8種。下面的組合是另一種:
2 5 9 11 16 17 19 21 22 24 26 30 31 33 35 36 41 46 47 50 52 61
如果告訴你該方案緊貼著上邊沿的是從左到右依次為:47 46 61,
你能計算出緊貼著下邊沿的是哪幾個正方形嗎?
請提交緊貼著下邊沿的正方形的邊長,從左到右,用空格分開。
不要填寫任何多餘的內容或說明文字。
2 5 9 11 16 17 19 21 22 24 26 30 31 33 35 36 41 46 47 50 52 61
答案:50 33 30 41
暴力深搜,想法沒問題,但是注意程式碼的規範問題,可以多些一些函式實現,更加規範,避免不必要的錯誤
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N=200; int mp[N][N]; int num[23]={0,2,5,9,11,16,17,19,21,22,24,26,30,31,33,35,36,41,46,47,50,52,61}; int book[30]; int isempty(int x,int y,int k) { for(int i=x;i<x+k;i++) { for(int j=y;j<y+k;j++) { if(mp[i][j]!=0) { return 0; } } } return 1; } void output() { for(int i=154;i<=154;i++) { for(int j=1;j<=154;j++) { printf("%d ",mp[i][j]); } printf("\n"); } return ; } void dfs(int x,int y) { if(x>154) { output(); return ; } if(mp[x][y]!=0) { if(y==154) dfs(x+1,1); else dfs(x,y+1); } else { for(int i=1;i<=22;i++) { if(book[i]==1||num[i]+x-1>154||num[i]+y-1>154||isempty(x,y,num[i])==0) { continue; } for(int k=x;k<num[i]+x;k++) { for(int j=y;j<y+num[i];j++) { mp[k][j]=num[i]; } } book[i]=1; if(y==154) dfs(x+1,1); else dfs(x,y+1); book[i]=0; for(int k=x;k<num[i]+x;k++) { for(int j=y;j<y+num[i];j++) { mp[k][j]=0; } } } } } void init() { for(int i=1;i<=47;i++) { for(int j=1;j<=47;j++) { mp[i][j]=47; } } for(int i=1;i<=46;i++) { for(int j=48;j<=47+46;j++) { mp[i][j]=46; } } for(int i=1;i<=61;i++) { for(int j=47+46+1;j<=47+46+61;j++) { mp[i][j]=61; } } } int main() { init(); dfs(47,46); return 0; }