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;
}

 

转载于:https://www.cnblogs.com/yohaha/p/5233606.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值