CodeForces - 711B Chris and Magic Square

CodeForces - 711B  Chris and Magic Square 

  题意:给你一个N*N矩阵,其中0代表未知的那个数,让你在这个位置填上一个数使整个矩阵的 每一行、每一列、主对角线、次对角线的和都相等。
 
  思路:一开始一直没理解题意,到底是行和=列和=对角线和,还是所以行的和相等,所有列的和相等,两条对角线的和相等。看到了are单词,明白了是第一种情况,之后就是简单的模拟了,特别判断n为1的情况,一定要注意细节,仔细仔细再仔细

#include<iostream>
using namespace std;
typedef long long ll;
const ll INF = 1e18;
ll r[505],c[505],angle[3];
ll a[505][505];
int main(void)
{
	int n;
	cin>>n;
	for(int i=1;i<=n;i++)
	    for(int j=1;j<=n;j++)
	        cin>>a[i][j];
	if(n==1)
	{
		cout<<1<<endl;
		return 0;
	}
	int u,v;
	for(int i=1;i<=n;i++)
	    for(int j=1;j<=n;j++)
	    {
		    r[i]+=a[i][j];
			c[i]+=a[j][i];
			
			if(a[i][j]==0)
			{
				u=i;
				v=j;
			}
			
			if(i==j) angle[1]+=a[i][j];
			if((i+j)==(n+1)) angle[2]+=a[i][j];
		}
	int flag=1;
	ll R;	
	for(int i=1;i<=n;i++)
	{
		if(i==u) continue;
		if(flag)
		{
			R=r[i];
			flag=0;
			continue;
		}
		if(r[i]!=R)
		{
			cout<<-1<<endl;
			return 0;
		}
	}
	ll C;
	flag=1;
	for(int i=1;i<=n;i++)
	{
		if(i==v) continue;
		if(flag)
		{
			C=c[i];
			flag=0;
			continue;
		}
		if(c[i]!=C)
		{
			cout<<-1<<endl;
			return 0;		
		}
	}
	if(R!=C)
	{
		cout<<-1<<endl;
		return 0;
	}
	if(u!=v&&(u+v)!=(n+1))
	{
		if(angle[1]==angle[2]&&angle[2]==R&&r[u]==c[v]&&R-r[u]>=1&&R-r[u]<=INF)
		{
			cout<<R-r[u]<<endl;
			return 0;
	    }
	    else
	    {
	    	cout<<-1<<endl;
	    	return 0;
	    }
	}
	if(u==v&&(u+v)!=(n+1))
	{
		if(r[u]==c[v]&&angle[1]+R-r[u]==angle[2]&&angle[2]==R&&R-r[u]>=1&&R-r[u]<=INF)
		{
			cout<<R-r[u]<<endl;
			return 0;
		}
		else
		{
			cout<<-1<<endl;
			return 0;
		}
	}
	if(u!=v&&(u+v)==(n+1))
	{
		if(r[u]==c[v]&&angle[2]+R-r[u]==angle[1]&&angle[1]==R&&R-r[u]>=1&&R-r[u]<=INF)
		{
			cout<<R-r[u]<<endl;
			return 0;
		}
		else 
		{
			cout<<-1<<endl;
			return 0;
		}
	}
	if(u==v&&(u+v)==(n+1))
	{
		if(r[u]==c[v]&&angle[2]==angle[1]&&angle[1]==c[v]&&R-r[u]>=1&&R-r[u]<=INF)
		{
			cout<<R-r[u]<<endl;
			return 0;
		}
		else
		{
			cout<<-1<<endl;
			return 0;
		}
	}
	return 0;	
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值