简单题。
找一个不存在$0$的行,计算这行的和(记为$sum$),然后就可以知道$0$那个位置应该填的数字(记为$x$)。
如果$x<=0$,那么无解,否则再去判断每一行,每一列以及两个斜对角的和是否均为$sum$。需要注意的是$n=1$的时候,直接输出$1$就可以了。
#pragma comment(linker, "/STACK:1024000000,1024000000") #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<vector> #include<map> #include<set> #include<queue> #include<stack> #include<iostream> using namespace std; typedef long long LL; const double pi=acos(-1.0),eps=1e-8; const int maxn=600; int n; LL a[maxn][maxn]; int r,c; int main() { scanf("%d",&n); for(int i=1; i<=n; i++) { for(int j=1; j<=n; j++) { scanf("%lld",&a[i][j]); if(a[i][j]==0) r=i, c=j; } } if(n==1) { printf("1 "); } else { int pos=-1; for(int i=1; i<=n; i++) { for(int j=1; j<=n; j++) if(i!=r) { pos=i; break; } if(pos!=-1) break; } LL sum=0; for(int j=1; j<=n; j++) sum=sum+a[pos][j]; LL sum2=0; for(int j=1; j<=n; j++) sum2=sum2+a[r][j]; a[r][c]=sum-sum2; if(a[r][c]<=0) printf("-1 "); else { bool fail=0; for(int i=1; i<=n; i++) { LL t=0; for(int j=1; j<=n; j++) t=t+a[i][j]; if(t!=sum) fail=1; } for(int j=1; j<=n; j++) { LL t=0; for(int i=1; i<=n; i++) t=t+a[i][j]; if(t!=sum) fail=1; } LL t=0; for(int i=1; i<=n; i++) t=t+a[i][i]; if(t!=sum) fail=1; t=0; for(int i=1; i<=n; i++) t=t+a[i][n-i+1]; if(t!=sum) fail=1; if(fail) printf("-1 "); else printf("%lld ",a[r][c]); } } return 0; }