1. 程式人生 > >藍橋杯2015——完美正方形(DFS 暴力搜尋)

藍橋杯2015——完美正方形(DFS 暴力搜尋)

如果一些邊長互不相同的正方形,可以恰好拼出一個更大的正方形,則稱其為完美正方形。

歷史上,人們花了很久才找到了若干完美正方形。比如:如下邊長的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, 你能計算出緊貼著下邊沿的是哪幾個正方形嗎?

請提交緊貼著下邊沿的正方形的邊長,從左到右,用空格分開。

不要填寫任何多餘的內容或說明文字。

參考:https://blog.csdn.net/qq_34446253/article/details/51470218 

#include<cstdio> #include<iostream>

using namespace std;

int arr[]={2,5,9,11,16,17,19,21,22,24,26,30,31,33,35,36,41,50,52,46,47,61}; int flagArr[19]={0}; int draw[155][155]={0};

bool judgment(int x,int y,int n){     //引數定義 n 表示正方形邊長     //1.如果超過畫布邊框 返回false     //2.如果畫的正方形與其他正方形重合 返回false     //else 返回true     if(!(x+n<=155&&y+n<=155)) return false;     for(int i=x;i<x+n;i++)         for(int j=y;j<y+n;j++)             if(draw[i][j]) return false;     return true; } void drawing(int x,int y,int n,int m){     //引數定義 n 表示正方形邊長 m 表示正方形編號     //從(x,y)處開始 畫長度為 n 的正方形 其編號為 m     for(int i=x;i<x+n;i++)         for(int j=y;j<y+n;j++)             draw[i][j]=m; } void getCoordinate(int &x,int &y){     //1.我們第一行已經知曉所以可以從46行開始搜尋     //找到我們搜尋的第一行值為0的說明此處未被畫 然後返回     for(int i=47;i<155;i++)         for(int j=1;j<155;j++)             if(!draw[i][j]){                 x=i;                 y=j;                 return;             } } bool solved(){     //如果全部都已賦值,則返回true     for(int i=47;i<155;i++)         for(int j=1;j<155;j++)             if(!draw[i][j]) return false;     return true; } bool dfs(int x,int y){     //深度搜索     //遞迴出口 solved為真,退出迴圈     //else 開始遍歷     /*     */     if(solved()) return true;     else{         getCoordinate(x,y);         for(int k=0;k<19;k++){             if(judgment(x,y,arr[k])){                 if(!flagArr[k]){                     drawing(x,y,arr[k],arr[k]);                     flagArr[k]=1;                     if(dfs(x,y+arr[k])) return true;                     flagArr[k]=0;                     drawing(x,y,arr[k],0);                 }             }             else break;             //退出迴圈原因:             /*    1.為什麼不先檢查 flagArr[k]?---只能選擇continue,不節約記憶體                  2.小的正方形都裝不下了,大的一定裝不下,所以沒必要迴圈下去             */         }     }     return false; } int main(){     drawing(1,1,47,47);     drawing(1,48,46,46);     drawing(1,94,61,61);     dfs(47,1);     for(int i=1;i<=154;i++){         cout<<draw[154][i]<<' ';         i+=draw[154][i];     }     return 0; }