第五届蓝桥杯软件类国赛真题-C-A-2_六角幻方


//第五届蓝桥杯软件类国赛真题-C-A-2_六角幻方
/*【题目】
标题:六角幻方

    把 1 2 3 ... 19 共19个整数排列成六角形状,如下:

    * * *
   * * * *
  * * * * *
   * * * * 
    * * *

    要求每个直线上的数字之和必须相等。共有15条直线哦!

    再给点线索吧!我们预先填好了2个数字,第一行的头两个数字是:15 13,
	参见图【p1.png】,黄色一行为所求。

    请你填写出中间一行的5个数字。数字间用空格分开。

    这是一行用空格分开的整数,请通过浏览器提交答案,
	不要填写任何多余的内容(比如说明性的文字等)

*/

/*【解题思路】
解法一:深度优先搜索,且逐步搜索时,逐步判断,降低算法时间复杂度 

答案:9 6 5 2 16
*/

#include<iostream>
using namespace std;

bool visit[19] = {false};//此变量用于标记17个未知圆圈上的数字是否已被访问过 
int a[17] = {0};//此变量用于表示17个未知圆圈上的数字

/*
 * @简介:深度优先搜索算法,搜索17个未知圆圈上的数字该填什么才符合题目条件 
 * @参数:currentStep表示当前搜索到了第几个圆圈 
 * @返回:无 
*/ 
void dfs(int currentStep)
{
	if(currentStep == 5)//当前已经搜索完第5个圆圈了,即搜索完a[0]~a[4] 
	{
		if(15+13+a[0] != a[1]+a[2]+a[3]+a[4])//是否符合题目条件:每个直线上的数字之和必须相等 
			return;							//不符合则return 
	}
	if(currentStep == 6)//当前已经搜索完第6个圆圈了,即搜索完a[0]~a[5]
	{
		if(15+13+a[0] != 15+a[1]+a[5])
			return;
	}
	if(currentStep == 10)
	{
		if(15+13+a[0] != a[5]+a[6]+a[7]+a[8]+a[9])
			return;
		else if(15+13+a[0] != a[0]+a[4]+a[9])
			return;
	}
	if(currentStep == 11)
	{
		if(15+13+a[0] != 13+a[2]+a[6]+a[10])
			return;
	}
	if(currentStep == 14)
	{
		if(15+13+a[0] != a[10]+a[11]+a[12]+a[13])
			return;
		else if(15+13+a[0] != 13+a[3]+a[8]+a[13])
			return;
	}
	if(currentStep == 15)
	{
		if(15+13+a[0] != a[5]+a[10]+a[14])
			return;
		else if(15+13+a[0] != a[0]+a[3]+a[7]+a[11]+a[14])
			return;
	}
	if(currentStep == 16)
	{
		if(15+13+a[0] != a[1]+a[6]+a[11]+a[15])
			return;
		else if(15+13+a[0] != a[4]+a[8]+a[12]+a[15])
			return;
	}
	if(currentStep == 17)
	{
		if(15+13+a[0] != a[14]+a[15]+a[16])
			return;
		else if(15+13+a[0] != 15+a[2]+a[7]+a[12]+a[16])
			return;
		else if(15+13+a[0] != a[9]+a[13]+a[16])
			return;
		else
		{
			for(int i=0;i<17;i++)
				cout<<a[i]<<" ";
			cout<<endl;
		}
	}
	else
	{
		for(int i=0;i<19;i++)//遍历数组visit[],查看1~19哪些数字被用过哪些数字没被用过 
		{
			if(!visit[i])//如果没被用过,表示该数字可填写在当前圆圈中 
			{
				a[currentStep] = i+1;//将该数字填写在当前圆圈中
				visit[i] = true;//将该数字标记为被用过 
				dfs(currentStep+1);//进行下一个圆圈的填数步骤 
				visit[i] = false;//将该数字标记为未被用过,即返回,方便其它子树搜索使用	
			}
		}
	}
} 

int main()
{
	visit[12] = visit[14] = true;//visit[12]、visit[14]分别表示数字13、15,
								//已经填写在第一二个圈里了,故标记为true,表示被用过 
	dfs(0);
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值