鸣谢
。。。201910131627798让我知道了最基础的bitset
代码(分析尽在其中)
/*
对于一二条件,可以分别在
O(n)O(n^2)的范围求出,对于条
件三,可以先转化为
a[i][j]<=max(a[i][k],b[j][k])
即为判断是否第i,j行有同时
小于a[i][j]的数.可以先把a[i][j]
从小到大排序,记录每一行出现的数
有哪些,只要用bitset存一下,判断
f[i],f[j]没有同时出现过的位即可
*/
#include<bits/stdc++.h>
using namespace std;
const int N=2600;
int n,cnt;
int a[N][N];
struct nkl
{
int val,x,y;
}s[N*N];
bitset<N>f[N];
inline bool god(nkl xx,nkl yy)
{
return xx.val<yy.val;
}
int main()
{
scanf("%d",&n);
for (int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
scanf("%d",&a[i][j]);
for (int i=1;i<=n;i++)
if(a[i][i])
{
puts("NOT MAGIC");
return 0;
}
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
if(a[i][j]!=a[j][i])
{
puts("NOT MAGIC");
return 0;
}
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
{
s[++cnt].x=i;
s[cnt].y=j;
s[cnt].val=a[i][j];
}sort(s+1,s+cnt+1,god);
for (int i=1,r;i<=cnt;i=r)
{
r=i;
while(r<=cnt&&s[i].val==s[r].val) r++;
for (int j=i;j<r;j++)
if((f[s[j].x]&f[s[j].y]).any())
{
puts("NOT MAGIC");
return 0;
}
for (int j=i;j<r;j++)
f[s[j].x][s[j].y]=1;
}
puts("MAGIC");
return 0;
}
京公网安备 11010502036488号