codeforces 632F. Magic Matrix
给一个n*n的矩阵, 问是否对角线上的元素全都为0, a[i][j]是否等于a[j][i], a[i][j]是否小于等于max(a[i][k], a[j][k]), k为任意值。
前两个都好搞, 我们来看第三个。 第三个的意思是, 对于a[i][j], 它小于等于第i行和第j行每一列的两个元素的最大值。
我们将矩阵中的每一个元素的值以及x, y坐标都加到一个数组里面, 然后从小到大排序。 从0到n-1枚举每一个i, 如果一个元素pos比i小, 那么就将b[pos的x][pos的y]这个数组值置为1, 直到剩下的元素值都比i大。 然后我们查看b[i的x], b[i的y] 这两行, 如果这两行的某一列两个值同时为1, 那么说明不满足。
具体可以看代码, b数组可以用一个bitset来代替。
#include <iostream> #include <vector> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <map> #include <set> #include <string> #include <queue> #include <stack> #include <bitset> using namespace std; #define pb(x) push_back(x) #define ll long long #define mk(x, y) make_pair(x, y) #define lson l, m, rt<<1 #define mem(a) memset(a, 0, sizeof(a)) #define rson m+1, r, rt<<1|1 #define mem1(a) memset(a, -1, sizeof(a)) #define mem2(a) memset(a, 0x3f, sizeof(a)) #define rep(i, n, a) for(int i = a; i<n; i++) #define fi first #define se second typedef pair<int, int> pll; const double PI = acos(-1.0); const double eps = 1e-8; const int mod = 1e9+7; const int inf = 1061109567; const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} }; const int maxn = 2502; bitset <maxn> b[maxn]; int a[maxn][maxn]; struct node { int x, y, val; bool operator < (node a)const { return val<a.val; } node(){} node(int _x, int _y, int _val):x(_x), y(_y), val(_val){} }q[maxn*maxn]; int main() { int n; cin>>n; for(int i = 0; i<n; i++) { for(int j = 0; j<n; j++) { scanf("%d", &a[i][j]); } } for(int i = 0; i<n; i++) { if(a[i][i]) { puts("NOT MAGIC"); return 0; } } for(int i = 0; i<n; i++) { for(int j = 0; j<n; j++) { if(a[i][j] != a[j][i]) { puts("NOT MAGIC"); return 0; } } } for(int i = 0; i<n; i++) { for(int j = 0; j<n; j++) { q[i*n+j] = node(i, j, a[i][j]); } } sort(q, q+n*n); int pos = 0; for(int i = 0; i<n*n; i++) { while(pos<n*n && q[pos].val<q[i].val) { b[q[pos].x][q[pos].y] = 1; pos++; } if((b[q[i].x]&b[q[i].y]).any()) { puts("NOT MAGIC"); return 0; } } puts("MAGIC"); return 0; }