题目链接:点击打开链接
大意:有N*N的矩阵,有一格是空的(标记为0),填一个数,使得每一行,每一列,两条对角线以及要填的数的这一行和这一列的和都相等,否则输出-1;
思路其实很简单,但代码太难写了(找BUG找了两天,气死了);
写个博客,记录一下;
思路:
分两条:
一
0在对角线上:1.在一条对角线上;
2.在两条对角线上;
二
0不在对角线上:不在对角线上;
#include<stdio.h>
#include<string.h>
long long map[550][550];//用long long ,否则爆表
int main()
{
int n;
while(~scanf("%d",&n))
{
int i,j;
int x,y;
memset(map,0,sizeof(map));
for(i=0; i<n; i++)
for(j=0; j<n; j++)
{
scanf("%lld",&map[i][j]);
if(map[i][j]==0)//记录0的横纵坐标
x=i,y=j;
map[i][n]+=map[i][j];//记录每一行的和
map[n][j]+=map[i][j];//记录每一列的和
}
if(n==1)//n为1时,可以是任意数,单列出来
{
printf("1\n");
continue;
}
int flag=-1;
//除了0所在的行和列外,其他行和列是否都相等
//相等为1,不相等为0;
long long xx,dui1=0,dui2=0,n1=0,n2=0;
//xx是记录其他行和列的值;
//dui1是记录左上角到右下角的对角线(第一条对角线),dui2是另一条对角线
//n1是记录第一条对角线有多少个不为零的数,n2是记录第二条对角线有多少个不为零的数,方便判断0的位置;
for(i=0; i<n; i++)
{
dui1+=map[i][i];
dui2+=map[i][n-i-1];
if(map[i][i]!=0) n1++;
if(map[i][n-i-1]!=0) n2++;
if(flag==-1&&i!=y)
xx=map[n][i],flag=1;
if(flag==-1&&i!=x)
xx=map[i][n],flag=1;
if(map[n][i]!=xx&&i!=y) flag=0;
if(map[i][n]!=xx&&i!=x) flag=0;
}
if(flag==1)//除了0所在的行和列的所有行和列都相等,
{
if(n1==n&&n2==n)//0不在对角线上;
{
if(xx==dui1&&dui1==dui2&&map[n][y]==map[x][n]&&xx>map[n][y])
printf("%lld\n",xx-map[n][y]);
else
printf("-1\n");
}
else if(n1!=n&&n2==n)//0在第一条对角线上;
{
if(xx==dui2&&dui1==map[n][y]&&dui1==map[x][n]&&dui2>dui1)
printf("%lld\n",dui2-dui1);
else
printf("-1\n");
}
else if(n1==n&&n2!=n)//0在第二条对角线上;
{
if(xx==dui1&&dui2==map[n][y]&&dui2==map[x][n]&&dui1>dui2)
printf("%lld\n",dui1-dui2);
else
printf("-1\n");
}
else if(n1!=n&&n2!=n)//0在两条对角线上;
{
if(dui1==dui2&&dui1==map[n][y]&&dui1==map[x][n]&&xx>dui1)
printf("%lld\n",xx-dui1);
else printf("-1\n");
}
}
else
printf("-1\n");
}
return 0;
}
总结:这一类题的方法都较简单,只是代码复杂,认真滤清思路