完美正方形-深度遍历

题目:如果一些边长互不相同的正方形,可以恰好拼出一个更大的正方形,则称其为完美正方形。

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, 你能计算出紧贴着下边沿的是哪几个正方形吗?

思路:深度搜索,将完美正方形看成154*154的方阵,将47,46,61分别放置在方阵各位并填写数值。根据行遍历,发现第一个为0的位置,开始按照a数组顺序填充数值,若judge判断成功且该数值未被访问过,则在方阵中填充此数并且标以访问。接下来以填充后的方阵开始深度遍历,继续发现第一个不为0的位置,如上,若judge判断失败则将之前填充的数值全部改为0,并且标记为未被访问。直到全部填充完整,深度遍历结束。

 

 

 1 #include<iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include<algorithm>
 5 #include<map>
 6 #define maxn 100010
 7 using namespace std;
 8 typedef long long LL;
 9 int a[19]= { 2,5,9,11,16,17,19,21,22,24,26,30,31,33,35,36,41,50,52};
10 int mat[154][154];
11 int visited[100];
12 void fill(int x, int y, int n, int s) {
13     for (int i = x; i < x + n; i++) {
14         for (int j = y; j < y + n; j++) {
15             mat[i][j] = s;
16         }
17     }
18 }
19 int solve() {
20     for (int i = 0; i < 154; i++) {
21         for (int j = 0; j < 154; j++) {
22             if (!mat[i][j]) {
23                 return 0;
24             }
25         }
26     }
27     return 1;
28 }
29 int judge(int x, int y, int n) {
30     if (x + n > 154 || y + n > 154) {
31         return 0;
32     }
33     for (int i = x; i < x + n; i++) {
34         for (int j = y; j < y + n; j++) {
35             if (mat[i][j]) {
36                 return 0;
37            }
38         }
39     }
40     return 1;
41 }
42 int dfs(int x, int y) {
43     if (solve()) {
44         return 1;
45     }
46     else {
47         int flag = 1;
48         for (int i = 0; i < 154 && flag; i++) {
49             for (int j = 0; j < 154 && flag; j++) {
50                 if (!mat[i][j]) {
51                     x = i, y = j, flag = 0;
52                 }
53             }
54 
55         }
56         for (int k = 0; k < 19; k++) {
57             if (judge(x, y, a[k])) {
58                 if (!visited[k]) {
59                     fill(x, y, a[k], a[k]);
60                     visited[k] = 1;
61                     cout << a[k] << " ";
62                     if (dfs(x, y + a[k])) {
63                         return 1;
64                     }
65                     fill(x, y, a[k], 0);
66                     visited[k] = 0;
67                 }
68             }
69             else{
70                 break;
71             }
72         }
73     }
74     return 0;
75 }
76 int main() {
77     memset(mat, 0, sizeof(mat));
78     memset(visited, 0, sizeof(visited));
79     fill(0, 0, 47, 47);
80     fill(0, 47, 46, 46);
81     fill(0, 93, 61, 61);
82     dfs(0, 0);
83     int ans = 0;
84     for (int i = 0; i < 154; i++) {
85         if (mat[153][i] != ans) {
86           //  cout << mat[153][i] << " ";
87             ans = mat[153][i];
88         }
89     }
90     return 0; 
91 }

 

posted @ 2020-07-08 00:34  吉吉的奥利奥  阅读(350)  评论(0编辑  收藏  举报