习题:Magic Matrix(bitset优化暴力)
题目
思路
阿这,这道题确实没有想到会是如此暴力的时间复杂度\(O(\frac{n^3}{32})\)
对于第一和第二个限制,相信可以不用过多阐释,直接暴力就可
看到这个常数,最容易想到的就是\(bitset\)
我们考虑按照权值的大小来填,填了的位置赋值为1,没有填的赋值为0
考虑我们要将权值为\(val\)的位置填上\(1\)
首先可以知道的一点权值小于\(val\)的位置上一定全是1
对于一个\(val\),其他的位置的值具体是什么其实并不重要,重要的是比val大还是比val小
对于\(a_{i,k}\)和\(a_{k,j}\)这两个位置,首先我们需要取一个max,用\(\&\)操作即可实现
我们考虑如果将i这一行和j这一列并起来,如果某一位上是1,即表示即使这意味上大的数依旧比val小,即不合法
代码
#include<iostream>
#include<algorithm>
#include<vector>
#include<bitset>
using namespace std;
struct node
{
int val;
int x,y;
friend bool operator < (const node &a,const node &b)
{
return a.val<b.val;
}
};
int n;
int a[2505][2505];
bitset<2505> g1[2505];
bitset<2505> g2[2505];
vector<node> v;
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
scanf("%d",&a[i][j]);
v.push_back((node){a[i][j],i,j});
}
for(int i=1;i<=n;i++)
{
if(a[i][i]!=0)
{
cout<<"NOT MAGIC";
return 0;
}
for(int j=1;j<=n;j++)
{
if(a[i][j]!=a[j][i])
{
cout<<"NOT MAGIC";
return 0;
}
}
}
sort(v.begin(),v.end());
v.push_back((node){-1,0,0});
for(int i=0;i<v.size()-1;i++)
{
int l=i;
while(v[i].val==v[i+1].val)
i++;
for(int j=l;j<=i;j++)
{
if((g1[v[j].x]&g2[v[j].y])!=0)
{
cout<<"NOT MAGIC";
return 0;
}
}
for(int j=l;j<=i;j++)
{
g1[v[j].x][v[j].y]=1;
g2[v[j].y][v[j].x]=1;
}
}
cout<<"MAGIC";
return 0;
}
/*
0
*/

浙公网安备 33010602011771号