时间限制1.00s 内存限制125.00MB 难易度:普及+/提高
【题目描述】
给一个 n×n 的方格矩阵,还有 n×n 个整数,让你将这些整数填入矩阵,使得每行每列每个对角线上整数的和都相等。下面给出几个例子:
【输入格式】
第一行一个整数 n (1≤n≤4)。
第二行 n×n 个整数 ai (−10^8≤ai≤10^8)。
【输出格式】
第一行一个整数 s 代表每行每列每个对角线的和值。
接下来输出一个 n×n 的矩阵,表示填数方案。
数据保证有解,可能存在多种方案,输出字典序最小的(将每行顺次相连之后,字典序最小)
【输入输出样例】
输入 #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函数)。
exit(0)比return更快,防止TLE。
【参考代码】
#include<bits/stdc++.h>
using namespace std;
int n,a[20];
int s=0,ans[20][20];
int sum,x,b[20];
bool check(int num)
{
num=0;
for(int i=1;i<=n;i++) num+=ans[1][i];
for(int i=2;i<=n;i++)
{
int cnt=0;
for(int j=1;j<=n;j++) cnt+=ans[i][j];
if(cnt!=num) return false;
}
for(int i=1;i<=n;i++)
{
int cnt=0;
for(int j=1;j<=n;j++) cnt+=ans[j][i];
if(cnt!=num) return false;
}
int cnt=0;
for(int i=1;i<=n;i++) cnt+=ans[i][i];
if(cnt!=num) return false;
cnt=0;
for(int i=1;i<=n;i++) cnt+=ans[i][n-i+1];
if(cnt!=num) return false;
return true;
}
void dfs(int x,int y)
{
if(y>n)
{
int cnt=0;
for(int i=1;i<=n;i++) cnt+=ans[x][i];
if(cnt!=sum/n) return;
x++;y=1;
}
if(x>n)
{
int cnt=0;
for(int i=1;i<=n;i++) cnt+=ans[1][i];
if(check(0))
{
cout<<cnt<<endl;
for(int i=1;i<=n;i++)
{
cout<<ans[i][1];
for(int j=2;j<=n;j++) cout<<" "<<ans[i][j];
cout<<endl;
}
x=cnt;
exit(0);
}
return;
}
for(int i=0;i<n*n;i++)
if(!b[i])
{
b[i]=1;
ans[x][y]=a[i];
dfs(x,y+1);
b[i]=0;
}
}
int main()
{
cin>>n;
for(int i=0;i<n*n;i++)
{
cin>>a[i];
sum+=a[i];
}
sort(a,a+n*n);
dfs(1,1);
return 0;
}