鸣谢
。。。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; }