P1406
方格填数
题目描述
给一个n*n的方格矩阵,还有n*n个整数,让你将这些整数填入矩阵,使得每行每列每个对角线上整数的和都相等。下面给出几个例子:
2 7 6
9 5 1
4 3 8

输入格式
输入格式
第一行一个整数n.(1<=n<=4)
第二行n*n个整数 ai (-108<=ai<=108)
输出格式
输出格式
第一行一个整数s 代表每行每列每个对角线的和值
接下来输出一个n*n的矩阵,表示填数方案。
数据保证有解,可能存在多种方案,输出字典序最小的(将每行顺次相连之后,字典序最小)
样例 #1
样例输入 #1
3
1 2 3 4 5 6 7 8 9
样例输出 #1
15
2 7 6
9 5 1
4 3 8
提示
数据范围
80% 1<=n<=3
100%1<=n<=4
服了 这题要求字典序最小 所以要先sort!!!
然后n=4不剪枝必TLE
只用加一个小优化即可 记录每行的和 若某行的和!=tot 则return
还要发现tot是可以提前算出来的
(这个P题卡了我好久……)
点击查看代码
#include<bits/stdc++.h>
using namespace std;
int n,tot,a[105],vis[105],jl[15][15],heng[10];
bool check()
{
int s=0;
for(int i=1;i<=n;i++)
{
s=0;
for(int j=1;j<=n;j++)
s+=jl[i][j];
if(s!=tot)return false;
}
for(int i=1;i<=n;i++)
{
s=0;
for(int j=1;j<=n;j++)
s+=jl[j][i];
if(s!=tot)return false;
}
s=0;
for(int i=1;i<=n;i++)s+=jl[i][i];
if(s!=tot)return false;
s=0;
for(int i=1;i<=n;i++)s+=jl[i][n+1-i];
if(s!=tot)return false;
return true;
}
void dfs(int x,int y)
{
if(x==n+1&&y==1)
{
if(check())
{
cout<<tot<<"\n";
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
cout<<jl[i][j]<<" ";
cout<<"\n";
}
exit(0);
}
return ;
}
if(x>1)
{
if(heng[x-1]!=tot)return ;
}
for(int i=1;i<=n*n;i++)
{
if(!vis[i])
{
jl[x][y]=a[i];
heng[x]+=a[i];
vis[i]=1;
if(y==n)dfs(x+1,1);
else dfs(x,y+1);
jl[x][y]=0;
heng[x]-=a[i];
vis[i]=0;
}
}
}
int main()
{
ios::sync_with_stdio(false);
cin>>n;
for(int i=1;i<=n*n;i++)
{
cin>>a[i];
tot+=a[i];
}
sort(a+1,a+n*n+1);
tot/=n;
dfs(1,1);
return 0;
}
此生无悔入OI 来生AK IOI

浙公网安备 33010602011771号