蓝桥杯题目练习 基础篇 [蓝桥杯2015决赛]四阶幻方

四阶幻方

题目描述

把1~16的数字填入4x4的方格中,使得行、列以及两个对角线的和都相等,满足这样的特征时称为:四阶幻方。
四阶幻方可能有很多方案。如果固定左上角为1,请计算一共有多少种方案。
比如:
1 2 15 16
12 14 3 5
13 7 10 4
8 11 6 9
以及:
1 12 13 8
2 14 7 11
15 3 10 6
16 5 4 9
就可以算为两种不同的方案。

输出

请提交左上角固定为1时的所有方案数字

暴力穷举

用16个for循环暴力穷举,需要保证数字不重复,还有当第一行之和,第二行之和,第三行之和,第四行之和不相等时,跳出本轮循环。
代码如下:

#include <iostream>
using namespace std;

int main(){
	int x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12,x13,x14,x15,x16;
	int a=0,b=0,c;
	int flag[17];
	int sum[11];
	for(int i=0;i<17;i++)
		flag[i]=0;
	for( x1=1;x1<=1;x1++){
		flag[x1]=1; 
		for(x2=2;x2<=16;x2++){
			if(flag[x2]==1) continue;
			else flag[x2]=1;
			for( x3=2;x3<=16;x3++){
				if(flag[x3]==1) continue;
				else flag[x3]=1;
				for(x4=2;x4<=16;x4++){
					if(flag[x4]==1) continue;
					else flag[x4]=1;
					sum[1]=x1+x2+x3+x4;
					if(sum[1]!=34){
						flag[x4]=0;
						if(x4==16) flag[x3]=0;
						if(x3==16) flag[x2]=0;
						if(x2==16) flag[x1]=0;
						continue;
					}
					for(x5=2;x5<=16;x5++){
						if(flag[x5]==1) continue;
						else flag[x5]=1;
						for(x6=2;x6<=16;x6++){
							if(flag[x6]==1) continue;
							else flag[x6]=1;
							for(x7=2;x7<=16;x7++){
								if(flag[x7]==1) continue;
								else flag[x7]=1;
								for(x8=2;x8<=16;x8++){
									if(flag[x8]==1) continue;
									else flag[x8]=1;
									sum[2]=x5+x6+x7+x8;
									if(sum[1] !=sum[2]){
										flag[x8]=0;
										if(x8==16) flag[x7]=0;
										if(x7==16) flag[x6]=0;
										if(x6==16) flag[x5]=0;
										continue;
									}
									for(x9=2;x9<=16;x9++){
										if(flag[x9]==1) continue;
										else flag[x9]=1;
										for(x10=2;x10<=16;x10++){
											if(flag[x10]==1) continue;
											else flag[x10]=1;
											for(x11=2;x11<=16;x11++){
												if(flag[x11]==1) continue;
												else flag[x11]=1;
												for(x12=2;x12<=16;x12++){
													if(flag[x12]==1) continue;
													else flag[x12]=1;
													sum[3]=x9+x10+x11+x12;
													if(sum[1]!=sum[3] || sum[3] !=sum[2] ){	
														if(x12==16) flag[x11]=0;
														if(x11==16) flag[x10]=0;
														if(x10==16) flag[x9]=0;
														flag[x12] = 0;
														continue;
													}
													for(x13=2;x13<=16;x13++){
														if(flag[x13]==1) continue;
														else flag[x13]=1;
														for(x14=2;x14<=16;x14++){
															if(flag[x14]==1) continue;
															else flag[x14]=1;
															for(x15=2;x15<=16;x15++){
																if(flag[x15]==1) continue;
																else flag[x15]=1;
																for(x16=2;x16<=16;x16++){
																	if(flag[x16]==1) continue;
																	else flag[x16]=1;
																	sum[4]=x13+x14+x15+x16;																	
																	sum[5]=x1+x5+x9+x13;
																	sum[6]=x2+x6+x10+x14;
																	sum[7]=x3+x7+x11+x15;
																	sum[8]=x4+x8+x12+x16;
																	sum[9]=x1+x6+x11+x16;
																	sum[10]=x4+x7+x10+x13;
																	a=0;
																	for(int i=2;i<=10;i++){
																		if(sum[i] == sum[i-1]) a++;
																	}
																	for(int i=1;i<=10;i++){
																		//cout<<sum[i]<<' ';
																	}
																//	cout<<endl;
																	//cout<<a;
																	if(a==9){
																		cout<<x1<<' '<<x2<<' '<<x3<<' '<<x4<<endl;
																		cout<<x5<<' '<<x6<<' '<<x7<<' '<<x8<<endl;
																		cout<<x9<<' '<<x10<<' '<<x11<<' '<<x12<<endl;
																		cout<<x13<<' '<<x14<<' '<<x15<<' '<<x16<<' '<<endl;
																		cout<<sum[10]<<endl;
																		b++;
																	}
																	flag[x16]=0;
																}
																flag[x15]=0;
															}
															flag[x14]=0;
														}
														flag[x13]=0;
													} 
													flag[x12]=0;
												} 
												flag[x11]=0;
											}
											flag[x10]=0;
										}
										flag[x9]=0;
									}
									flag[x8]=0;
								}
								flag[x7]=0;
							}
							flag[x6]=0;
						}
						flag[x5]=0;
					}
					flag[x4]=0;
				}
				flag[x3]=0;
			}
			flag[x2]=0;
		}
		flag[x1]=0;
	}
	cout<<b;					
	return 0;
}

答案是416.

暴力DFS:

#include <iostream>
#include <algorithm>
using namespace std;
int ans[17];
int sum[11];
int num[17];
bool vis[17];
int temp=0;
int dfs(int index){
//	cout<<ans[index];
	if(index==5){
		sum[1]=ans[1]+ans[2]+ans[3]+ans[4];
		
	}
	if(index==9){
		sum[2]=ans[5]+ans[6]+ans[7]+ans[8];
		if(sum[2]!=sum[1])	return 0;
	}
	if(index==13){
		sum[3]=ans[9]+ans[10]+ans[11]+ans[12];
		if(sum[3]!=sum[1])	return 0;
	}
	if(index==14){
		sum[5]=ans[1]+ans[5]+ans[9]+ans[13];
		sum[9]=ans[4]+ans[7]+ans[10]+ans[13];
		if(sum[5]!=sum[1] || sum[9]!=sum[1]) return 0;
	}
	if(index==15){
		sum[6]=ans[2]+ans[6]+ans[10]+ans[14];
		if(sum[6]!=sum[1]) return 0;
	}
	if(index==16){
		sum[7]=ans[3]+ans[7]+ans[11]+ans[15];
		if(sum[7]!=sum[1]) return 0;
	}
	if(index==17){
		sum[4]=ans[13]+ans[14]+ans[15]+ans[16];
		sum[8]=ans[4]+ans[8]+ans[12]+ans[16];
		sum[10]=ans[1]+ans[6]+ans[11]+ans[14];
		if(sum[4]!=sum[1] || sum[8]!=sum[1] || sum[10]!=sum[1]) return 0;
		for(int i=1;i<=16;i++){
			cout<<ans[i]<<' ';
			if(i%4==0) cout<<endl;
		}
		cout<<sum[10]<<endl;
		temp++;
		return 0;
	}
	for(int i=1;i<17;i++){
		if(!vis[i]){
			vis[i]=true;
			ans[index]=i;
			dfs(index+1);
			vis[i]=false;
			
		}
	}
	return 0;
}
int main(){
	for(int i=1;i<17;i++){
		num[i]=i;
		vis[i]=false;
	}
	ans[1]=1; vis[1]=true;
	dfs(2);
	cout<<temp;
	return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值