蓝桥杯 幻方填空

本文介绍了一种解决4阶幻方问题的方法,利用深度优先搜索算法填充剩余未知数字,确保每行、每列及对角线数字之和相等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

幻方填空

    幻方是把一些数字填写在方阵中,使得行、列、两条对角线的数字之和都相等。

    欧洲最著名的幻方是德国数学家、画家迪勒创作的版画《忧郁》中给出的一个4阶幻方。

    他把1,2,3,...16 这16个数字填写在4 x 4的方格中。

    如图p1.jpg所示,即:


16 ?  ?  13
?  ?  11 ?
9  ?  ?  *
?  15 ?  1

    
表中有些数字已经显露出来,还有些用?和*代替。

    请你计算出? 和 * 所代表的数字。并把 * 所代表的数字作为本题答案提交。


答案是一个整数,请通过浏览器直接提交该数字。

答案:12



深搜



#include <stdio.h>
#include <string.h>
int map[17];
bool vis[17];
int sum[10];
bool flag;
void dfs(int x)
{
	if(flag)
		return;
	if(x > 16)
	{
		sum[0] = map[1] + map[2] + map[3] + map[4];
		sum[1] = map[5] + map[6] + map[7] + map[8];
		sum[2] = map[9] + map[10] + map[11] + map[12];
		sum[3] = map[13] + map[14] + map[15] + map[16];
		sum[4] = map[1] + map[5] + map[9] + map[13];
		sum[5] = map[2] + map[6] + map[10] + map[14];
		sum[6] = map[3] + map[7] + map[11] + map[15];
		sum[7] = map[4] + map[8] + map[12] + map[16];
		sum[8] = map[1] + map[6] + map[11] + map[16];
		sum[9] = map[4] + map[7] + map[10] + map[13];
		for(int i = 0; i < 9; i++)
			if(sum[i] != sum[i + 1])
				return;
		flag = true;
		printf("%d\n", map[12]);
		return;
	}
	if(x == 1 || x == 4 || x == 7 || x == 9 || x == 14 || x == 16)
	{
		dfs(x + 1);
		return;
	}
	for(int i = 1; i <= 16; i++)
	{
		if(!vis[i])
		{
			vis[i] = true;
			map[x] = i;
			dfs(x + 1);
			vis[i] = false;
		}
	}	
}
int main()
{
	memset(vis, 0, sizeof(vis));
	map[1] = 16;
	vis[16] = true;
	map[4] = 13;
	vis[13] = true;
	map[7] = 11;
	vis[11] = true;
	map[9] = 9;
	vis[9] = true;
	map[14] = 15;
	vis[15] = true;
	map[16] = 1;
	vis[1] = true;
	flag = false;
	dfs(1);
	return 0;
}


### 关于蓝桥杯竞赛中的最大子矩阵问题 #### 子矩阵的最大累加和算法分析 对于子矩阵的最大累加和这一类题目,核心挑战在于如何高效地遍历所有可能的子矩阵并找到其中具有最大累加和的那个。直接枚举所有的子矩阵组合显然不是一种有效的方法,因为随着矩阵尺寸的增长,这种暴力搜索的时间复杂度会急剧增加。 为了优化这个问题,可以采用降维策略来简化计算过程。具体来说,可以通过先对每一列求累积和的方式将二维问题转化为一系列的一维问题处理[^1]。这样做的好处是可以利用已经成熟的动态规划技术快速定位到最优解的位置。 当把原始矩阵转换成多个一维序列之后,就可以应用经典的 Kadane&#39;s Algorithm 来查找这些序列里的连续子数组拥有最大的总和。该算法能够在 O(n) 的时间复杂度内完成任务,从而大大提高了整体效率。 ```python def max_subarray_sum(nums): current_max = global_max = nums[0] for num in nums[1:]: current_max = max(num, current_max + num) if current_max > global_max: global_max = current_max return global_max ``` 接着,在实际编码过程中还需要注意边界条件以及输入数据类型的验证等问题以确保程序健壮性和准确性。 #### 使用前缀和与双指针优化解决方案 除了上述提到的方法外,另一种常见的技巧是通过构建二维前缀和表配合双指针扫描来进行更高效的解答。这种方法能够进一步减少不必要的重复运算次数,特别是在面对较大规模的数据集时表现尤为突出[^2]。 创建一个额外的空间存储从起点至当前位置为止的所有元素之和作为辅助结构;随后固定上下两条边界的坐标位置形成窗口,并在这个范围内移动左右两侧端点直至覆盖整个宽度范围内的每一个潜在候选区域。期间不断更新记录当前已知的最佳结果直到结束循环即可获得最终答案。 ```python from itertools import accumulate def max_sum_submatrix(matrix, k=None): # 如果给定k,则表示不超过k的最大子矩阵和 rows, cols = len(matrix), len(matrix[0]) result = float(&#39;-inf&#39;) for l in range(cols): row_sums = [0] * rows for r in range(l, cols): for i in range(rows): row_sums[i] += matrix[i][r] accu_list = list(accumulate(row_sums)) if not k: # 不限k的情况下直接找最大值 temp_result = max_subarray_sum(accu_list) result = max(result, temp_result) else: # 需要满足<=k约束条件下寻找最佳方案 prefix_set = set([0]) curr_accu = 0 for val in accu_list: curr_accu += val prev = next((x for x in sorted(prefix_set, reverse=True) if (curr_accu-x)<=k), None) if prev is not None and ((curr_accu-prev)>result or result==float(&#39;-inf&#39;)): result = min(k, curr_accu - prev) prefix_set.add(curr_accu) return result ``` 此段代码实现了基于前缀和与双指针相结合的方式来解决问题,既考虑到了一般情况下的无限制求最值场景也兼顾了特定数值上限的要求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值