四阶幻方
题目描述
把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;
}