之前第2个点A了其他WA了。现在改改第2个点WA了,其他点A了。。。。。。
void prt()
{//用来输出方格的样子的函数
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++)
{if(j!=n)cout << ans[i][j] << ' ';
else cout << ans[i][j]<< endl; }}
cout << endl;
}
void dfs(int x, int y)
{
int dx, dy,s;
if(y==n && suml[x]!=sum)return ;//如果到头了总和不对就剪枝
if(y==n && x==n && sumx2!=sum)return ;//如果到了右下角对角线和不对就回去
if(y==1 && x==n && sumx1!=sum)return ;//如果到了左下角对角线和不对就回去
if(x==n && sumr[y]!=sum)return ;//如果到了最后一行,检验列的和
if(x==n && y==n){j=1;return;}//到了最后,啥都行了,可以回溯到主函数了
if(y==n)dx=x+1,dy=1;
else dx=x,dy=y+1;//算出下一个遍历的位置
int i;
for(i=1;i<=N;i++)
{//遍历可以用的数
if(!mrk[i])//如果该数没用过
{
s=sto[i];//记录当前遍历点的值
suml[dx]+=s;//算行的总和
sumr[dy]+=s;//算列的总和
if(dx+dy-1==n)sumx1+=s;
if(dx-dy+n==n)sumx2+=s;//如果点在对角线上就加上
mrk[i]=1;//标记当前点用了
ans[dx][dy]=s;//记录答案的方块长啥样
dfs(dx,dy);
if(j)return;//得出答案后快速回溯
ans[dx][dy]=0;
mrk[i]=0;
suml[dx]-=s;
sumr[dy]-=s;
if(dx+dy-1==n)sumx1-=s;
if(dx-dy+n==n)sumx2-=s;
//以上六行都是dfs后用于复原的
}
}
}
int main()
{
cin >> n;
N =n*n;//算出总的数的个数
for(int i=1;i<=N;i++)
{
cin >> sto[i];
sum+=sto[i];
}
sum=sum/n;//算出sum的值
sort(sto+1,sto+1+N);
memset(mrk,0,sizeof(mrk));
dfs(1, 0);
cout << sum << endl;
prt();
return 0;
}