B. Chris and Magic Square

题目链接:点击打开链接

大意:有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;
}




总结:这一类题的方法都较简单,只是代码复杂,认真滤清思路


     

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值