[作业] 六角填数问题

题目

题目来自csdn每日一刷

在这里插入图片描述
如上图六角星,有12个孔,每个孔按上面编号,各填入不重复的1~12个数,并使每条线的上的总和相等。要求输入前3个数字后,生成剩余的数字。

结果

input 3 nums:1 8 2
FIND the res:
1 8 2 9 7 11 10 12 3 5 6 4
each line num is:
26 26 26 26 26 26
input 3 nums:5 9 1
FIND the res:
5 9 1 4 5 3 6 10 2 3 4 5
each line num is:
19 19 19 19 19 19

代码

思路,使用递归 ,前项遍历确定后,再遍历后一项

#include

const int one_line_count = 4;
const int line_count = 6;
const int index_count = one_line_count * line_count;
int line_indexes[] = {
	2, 3, 4, 5,
	1, 3, 6, 8,
	1, 4, 7, 11,
	8, 9, 10 ,11,
	2, 6, 9, 12,
	5, 7, 10, 12
};
const int num_count = 12;

bool _fill_six_angle(int* num_in_hole, int step) {
	if (step >= num_count) {
		// 计算所有线是否相等
		int old_total = 0;
		for (int i = 0; i < line_count; ++i) {
			int cur_total = 0;
			for (int j = 0; j < one_line_count; ++j) {
				int ci = i * one_line_count + j;
				int ti = line_indexes[ci] -1;
				cur_total += num_in_hole[ti];
			}
			if (old_total != 0 && old_total != cur_total)
				return false;
			old_total = cur_total;
		}
		return true;
	}
	// 从12个数字里遍历
	for (int j = 0; j < num_count; ++j) {
		// 不能跟前面的数字相同
		for (int k = 0; k < step; ++k) {
			if (num_in_hole[k] == j + 1) {
				++j;
			}
		}
		if (j >= num_count)
			return false;
		num_in_hole[step] = j + 1;
		// 遍历后面
		if (_fill_six_angle(num_in_hole, step + 1))
			return true;
	}
	return false;
}

void fill_six_angle(int* pre_nums, int pre_count) {
	int num_in_hole[num_count]; // 编号对应的数字 
	memset(num_in_hole, 0, sizeof(num_in_hole));
	memcpy(num_in_hole, pre_nums, sizeof(int) * pre_count);

	bool res = _fill_six_angle(num_in_hole, pre_count);
	
	if (res) {
		std::cout << "FIND the res: " << std::endl;
		for (int i = 0; i < num_count; ++i) {
			std::cout << " " << num_in_hole[i];
		}
		std::cout << std::endl << "each line num is:" << std::endl;
		for (int i = 0; i < line_count; ++i) {
			int cur_total = 0;
			for (int j = 0; j < one_line_count; ++j) {
				int ci = i * one_line_count + j;
				int ti = line_indexes[ci] - 1;
				cur_total += num_in_hole[ti];
			}
			std::cout << " " <<cur_total;
		}
	}
	else {
		std::cout << "FAIL to get the result!!" << std::endl;
	}

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值