测评会员优惠活动进行中 · 开通 VIP,有效期内测评不限次 VIP 优惠中 · 测评不限次 立即查看

A40862. 完美正方形

填空题 困难

题目描述

完美正方形

题目描述

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

历史上,人们花了很久才找到了若干完美正方形。

比如:如下边长的 22 个正方形:2 3 4 6 7 8 12 13 14 15 16 17 18 21 22 23 24 26 27 28 50 60

如图这样组合,就是一种解法。

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

答案提交

请提交紧贴着下边沿的正方形的边长,从左到右,用空格分开。

不要填写任何多余的内容或说明文字。

参考答案

#include <iostream> using namespace std; const int N = 200; int g[N][N]; bool st[N], cnt[N]; int s[22] = {2, 5, 9, 11, 16, 17, 19, 21, 22, 24, 26, 30, 31, 33, 35, 36, 41, 46, 47, 50, 52, 61}; bool judge(int x, int y, int len) // 判断从 (x, y) 起,能否添加边长为 len 的正方形 { if(x + len - 1 > 154 || y + len - 1 > 154) return false; // 出界 for (int i = x; i < x + len; i ++) for (int j = y; j < y + len; j ++) if(g[i][j]) return false; // 该点已经被包含在其它正方形内 return true; } void add(int x, int y, int len, int num) // 从 (x, y) 起,添加边长为 len 的正方形 { for (int i = x; i < x + len; i ++) for (int j = y; j < y + len; j ++) g[i][j] = num; } void dfs(int x, int y) { if(y == 154) x ++, y = 1; // 换行 if(x == 155) // 输出答案 { for (int i = 1; i <= 154; i ++) if(!cnt[g[154][i]]) { cout << g[154][i] << " "; cnt[g[154][i]] = true; } } if(!g[x][y]) // 该点还未被填充 { for (int i = 0; i < 22; i ++) if(!st[i] && judge(x, y, s[i])) { st[i] = true; add(x, y, s[i], s[i]); dfs(x, y + 1); add(x, y, s[i], 0); // 回溯 st[i] = false; } } else dfs(x, y + 1); } int main() { add(1, 1, 47, 47); add(1, 48, 46, 46); add(1, 94, 61, 61); dfs(1, 1); return 0; }
上一题 下一题