蓝桥杯 完美正方形 【dfs】

本文探讨了如何通过网格化和染色算法解决完美正方形拼接问题,使用C++实现了一个具体的解决方案,展示了如何避免正方形重叠并完全填充大正方形。

标题:完美正方形

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

历史上,人们花了很久才找到了若干完美正方形。比如:如下边长的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,
你能计算出紧贴着下边沿的是哪几个正方形吗?

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

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

思路:
meshgrid ----,网格化(即50*50的正方形由50*50个像素点组成),然后就变成了染色问题~。在左上角摆47*47的正方形即把以(1,1)~(47,47)这些像素点染成颜色47。注意染过色的像素点不能二次染色,即一个正方形不能覆盖另一个正方形。 恰好能将全部像素点染色,就是本题的解。

Code

#include <bits/stdc++.h>
using namespace std;
int a[] = {0,2,5,9,11,16,17,19,21,22,24,26,30,31,33,35,36,41,46,47,50,52,61};
int len,mp[201][201];
bool book[101];
bool Judge(int x,int y,int num)
{
	if(x+num-1 > len || y+num-1 > len)
		return false;
	for(int i=x;i<x+num;i++) 
		for(int j=y;j<y+num;j++)
			if(mp[i][j])
				return false;
	return true;
}
void color(int x,int y,int num)
{
	int l; 
	if(num == 0) {	
		book[mp[x][y]] = false;
		l = mp[x][y];
	}
	else {
		book[num] = true;
		l = num;
	} 
	for(int i=x;i<x+l;i++) 
		for(int j=y;j<y+l;j++)
			mp[i][j] = num;
}
bool flag;
void dfs(int x,int y)
{
	if(x == len+1) {
		flag = true;
		return ;
	}
	if(mp[x][y]) {
		if(y == len)
			dfs(x+1,1);
		else
			dfs(x,y+1);
		return;
	}
	for(int i=1;i<=22;i++) {
		if(book[a[i]])
			continue;
		if(!Judge(x,y,a[i]))
			break;	//a[i]随着i增大而增大,因此没必要在试下去
		color(x,y,a[i]);
		if(y == len)
			dfs(x+1,1);
		else
			dfs(x,y+1);
		if(flag)
			return;
		color(x,y,0);
	}

}
int main()
{
	len = 47+46+61;
	flag = false;
	memset(mp,0,sizeof mp);
	memset(book,false,sizeof book);

	color(1,1,47);
	color(1,1+47,46);
	color(1,1+47+46,61);
	
	dfs(1,1);
	
	int colorr=-1;
	for(int i=1;i<=len;i++) {
		if(mp[len][i] != colorr) {
			colorr = mp[len][i];
			printf("%d ",colorr);
		}
	}

	return 0;
}

 

### 蓝桥杯正方形 算法题 解法 #### 计算矩形相交部分的面积 当涉及到两个矩形相交区域的面积计算时,可以采用几何方法来解决。假设我们有两个矩形 A 和 B,分别由左下角坐标 `(xA1, yA1)` 和右上角坐标 `(xA2, yA2)` 定义;另一个矩形 B 则由 `(xB1, yB1)` 和 `(xB2, yB2)` 定义。 要找到它们重叠的部分,可以通过以下方式实现: - 首先判断是否有重叠的可能性:如果 `xA2 < xB1` 或者 `xB2 < xA1` 或者 `yA2 < yB1` 或者 `yB2 < yA1`,则说明两矩形不相交。 - 如果有重叠,则通过取最大值和最小值得到重叠区域的边界: - 左下角横坐标为 `max(xA1, xB1)` - 右上角横坐标为 `min(xA2, xB2)` - 左下角纵坐标为 `max(yA1, yB1)` - 右上角纵坐标为 `min(yA2, yB2)` 最终重叠区域的宽度为 `rightX - leftX`,高度为 `topY - bottomY`,注意需要验证这两个差值是否大于零以避免负数情况[^1]。 ```python def intersect_area(rect_a, rect_b): xa1, ya1, xa2, ya2 = rect_a xb1, yb1, xb2, yb2 = rect_b overlap_x_start = max(xa1, xb1) overlap_y_start = max(ya1, yb1) overlap_x_end = min(xa2, xb2) overlap_y_end = min(ya2, yb2) width = max(0, overlap_x_end - overlap_x_start) height = max(0, overlap_y_end - overlap_y_start) return width * height ``` #### 正方形切割问题 对于正方形切割问题,通常会涉及最大化利用材料或者均匀分配资源的情况。例如,在一块大巧克力板中切出尽可能多的小正方形巧克力块,并且这些小正方形大小一致。 一种有效的方法是使用 **二分查找算法** 来寻找最大的可行边长 \(x\) ,使得能够从中切出至少 K 块尺寸为 \(x \times x\) 的正方形。具体来说,设原始巧克力板的长度为 L,宽度为 W,则每种尝试的边长 \(x\) 下可获得的正方形数量应为 \((L // x) \cdot (W // x)\)[^3]。 以下是基于此逻辑的一个 Python 实现例子: ```python def max_square_size(L, W, K): low, high = 1, min(L, W) result = 0 while low <= high: mid = (low + high) // 2 count = (L // mid) * (W // mid) if count >= K: result = mid low = mid + 1 else: high = mid - 1 return result ``` 上述函数接受三个参数——巧克力板的长度、宽度以及目标分割成的正方形单元数目 K ——并返回满足条件的最大可能边长。 #### 结论 无论是处理矩形间的相互作用还是优化正方形划分策略,都需依赖清晰定义的问题框架与适当的数据结构支持下的高效算法设计。以上两种情形展示了不同类型的几何运算技巧及其实际应用价值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值