【题目名称】幻方
【题目描述】
有一个n*n的方阵,其中有且仅有一个位置是空的,其余位置都填有正整数。现在需要在空位处填入一个正整数,使得该方阵每一行的数之和,每一列的数之和,以及主、副对角线上的数之和都相等。
现在需要用程序来判断是否能够找到满足要求的正整数。如果能,请输出满足要求的正整数,(如果有多解,输出任意解即可);如果不能,请输出-1.
【输入格式】
第1行,一个正整数n.(1<=n<=500);
接下来的n行,输入n*n的方阵。空位处用数字0表示,其余位置的数保证为正整数。(范围:1<=x<=10^9);
【输出格式】
共一行,按照题目描述输出一个正整数。
【样例输入1】
3
4 0 2
3 5 7
8 1 6
【样例输出1】
9
【样例输入2】
4
1 1 1 1
1 1 0 1
1 1 1 1
1 1 1 1
【样例输出2】
1
【样例输入3】
4
1 1 1 1
1 1 0 1
1 1 2 1
1 1 1 1
【样例输出3】
-1
【题解】
此题只需记下空位的坐标,然后以其中某行某列的和作为目标值,计算空位的数值即可。
需要判断是否无解。注意当计算出空位的数值为0或负数时,也应判为无解。
n==1时有多解,打出任意正整数即可。
【参考代码】
#include<cstdio>
#define ll long long
ll a[510][510];
ll sum[1020];
int n,X,Y;
int main()
{
scanf("%d",&n);
if(n==1)
{
printf("1");
return 0;
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
scanf("%I64d",&a[i][j]);
sum[i]+=a[i][j];
sum[n+j]+=a[i][j];
if(i==j)
{
sum[2*n+1]+=a[i][j];
}
if(i+j==n+1)
{
sum[2*n+2]+=a[i][j];
}
if(a[i][j]==0)
{
X=i;
Y=j;
}
}
}
ll tmp=0;
for(int i=1;i<=n;i++)
{
if(i!=X)
{
if(tmp==0)
{
tmp=sum[i];
}
else if(tmp!=sum[i])
{
printf("-1");
return 0;
}
}
}
for(int j=1;j<=n;j++)
{
if(j!=Y)
{
if(tmp==0)
{
tmp=sum[j+n];
}
else if(tmp!=sum[j+n])
{
printf("-1");
return 0;
}
}
}
if(X!=Y)
{
if(tmp==0)
{
tmp=sum[2*n+1];
}
else if(tmp!=sum[2*n+1])
{
printf("-1");
return 0;
}
}
if(X+Y!=n+1)
{
if(tmp==0)
{
tmp=sum[2*n+2];
}
else if(tmp!=sum[2*n+2])
{
printf("-1");
return 0;
}
}
ll ans;
ans=tmp-sum[X];
if(ans<=0)
{
printf("-1");
return 0;
}
if((sum[n+Y]+ans)!=tmp)
{
printf("-1");
return 0;
}
if(X==Y)
{
if((sum[2*n+1]+ans)!=tmp)
{
printf("-1");
return 0;
}
}
if(X+Y==n+1)
{
if((sum[2*n+2]+ans)!=tmp)
{
printf("-1");
return 0;
}
}
printf("%I64d",ans);
return 0;
}</span>