蓝桥杯第五届 六角填数

标题:六角填数


    如图【1.png】所示六角形中,填入1~12的数字。


    使得每条直线上的数字之和都相同。


    图中,已经替你填好了3个数字,请你计算星号位置所代表的数字是多少?


请通过浏览器提交答案,不要填写多余的内容。



解题思路:

1.用回溯法就可以把每个位置的数就可以穷举一次。遇到合适的就结束输出。

2.源代码中用vis数组来标记哪个数字已经被使用过,dfs中用n来表示位置,i表示要赋的值。

3.关键要点就是写好函数中刚开始需要的值和回溯的出口。函数里面的for记得要枚举一个标记后再重新成为未标记。

4.从上到下依次标记为1-12。


源代码:

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string>
#include<string.h>
#include<math.h>
#include<map>
#include<vector>
#include<algorithm>
#include<stack>
#include<queue>
using namespace std;
#define MAX 0x3f3f3f3f
#define MIN -0x3f3f3f3f
int ans[13];
bool vis[13];
void dfs(int n)
{
	if(n==1||n==2||n==12)
	{
		dfs(n+1);
		return; 
	}
	if(n>=13)
	{
		int t[6];
		t[0]=ans[1]+ans[3]+ans[6]+ans[8];
		t[1]=ans[1]+ans[4]+ans[7]+ans[11];
		t[2]=ans[8]+ans[9]+ans[10]+ans[11];
		t[3]=ans[2]+ans[3]+ans[4]+ans[5];
		t[4]=ans[2]+ans[6]+ans[9]+ans[12];
		t[5]=ans[5]+ans[7]+ans[10]+ans[12];
		for(int i=1;i<=5;i++)
		{
			if(t[i]!=t[i-1])
			{
				return;
			}
		}
		printf("%d
",ans[6]);
		return;

	}
	for(int i=1;i<=12;i++)
	{
		if(!vis[i])
		{
			vis[i]=true;
			ans[n]=i;
			dfs(n+1);
			vis[i]=false;	
		}
	}
}
int main(int argc, char *argv[]) 
{
	memset(ans,0,sizeof(ans));
	ans[1]=1;
	ans[2]=8;
	ans[12]=3;
	vis[1]=vis[3]=vis[8]=1;
	dfs(1);
	return 0;
}


原文地址:https://www.cnblogs.com/lemonbiscuit/p/7776140.html