四阶幻方-蓝桥杯-DFS
答案:416
用next_permutation()全部排列的话会超时
所以用dfs搜索,只搜索前三行就好,前三行确定之后,第四行也就确定
#include<iostream> #include<string> #include<string.h> #include<algorithm> using namespace std; int vis[17],a[5][5]; int ans=0; int check(int x,int y) { if(x<3)//只枚举到前三行就可以,如果前三行符合条件,那么最后一行四个数之和一定是34 { if(y<3)//一行还没有放满4个,前三个数可以随便取 return 1; if(a[x][0]+a[x][1]+a[x][2]+a[x][3]==34) return 1; else { return 0; } } else//x==3 { if(y==0)//判断第1列和副对角线 { if((a[0][0]+a[1][0]+a[2][0]+a[3][0]!=34)||(a[0][3]+a[1][2]+a[2][1]+a[3][0]!=34)) return 0; } if(y==1||y==2)//判断第2列和第3列 if(a[0][y]+a[1][y]+a[2][y]+a[3][y]!=34) return 0; if(y==3)//判断第4列和主对角线 if((a[0][y]+a[1][y]+a[2][y]+a[3][y]!=34)||(a[0][0]+a[1][1]+a[2][2]+a[3][3])!=34) return 0; else { return 1; } } } void dfs(int x,int y) { if(x==4) { ans++; return ; } // else if(y>3) // dfs(x+1,0); else { for(int i=2;i<=16;i++) { if(vis[i]==0) { vis[i]=1; a[x][y]=i; if(check(x,y)) { if(y<3) dfs(x,y+1); else dfs(x+1,0); } vis[i]=0; } } } } int main() { a[0][0]=vis[1]=1; dfs(0,1); cout<<ans<<endl; system("pause"); return 0; }
等风起的那一天,我已准备好一切