Bit Magic
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3421 Accepted Submission(s): 959
Problem Description
Yesterday, my teacher taught me about bit operators: and (&), or (|), xor (^). I generated a number table a[N], and wrote a program to calculate the matrix table b[N][N] using three kinds of bit operator. I thought my achievement would get teacher's attention.
The key function is the code showed below.
There is no doubt that my teacher raised lots of interests in my work and was surprised to my talented programming skills. After deeply thinking, he came up with another problem: if we have the matrix table b[N][N] at first, can you check whether corresponding number table a[N] exists?
The key function is the code showed below.
![](https://i-blog.csdnimg.cn/blog_migrate/9a7e64e0b86d3c9a41c936d80315fded.png)
There is no doubt that my teacher raised lots of interests in my work and was surprised to my talented programming skills. After deeply thinking, he came up with another problem: if we have the matrix table b[N][N] at first, can you check whether corresponding number table a[N] exists?
Input
There are multiple test cases.
For each test case, the first line contains an integer N, indicating the size of the matrix. (1 <= N <= 500).
The next N lines, each line contains N integers, the jth integer in ith line indicating the element b[i][j] of matrix. (0 <= b[i][j] <= 2 31 - 1)
For each test case, the first line contains an integer N, indicating the size of the matrix. (1 <= N <= 500).
The next N lines, each line contains N integers, the jth integer in ith line indicating the element b[i][j] of matrix. (0 <= b[i][j] <= 2 31 - 1)
Output
For each test case, output "YES" if corresponding number table a[N] exists; otherwise output "NO".
Sample Input
2 0 4 4 0 3 0 1 24 1 0 86 24 86 0
Sample Output
YES NO
Source
Recommend
zhuyuanchen520
题目大意:
给一个有一个N维向量通过一定的逻辑运算得到的矩阵,问存在不存在一个N维向量满足要求。
解题思路:
一看到给出逻辑运算结果,求存在不存在,马上就能想到时2-SAT。
不过这里的每个元素都是整数,而不是布尔类型,我们就可以把正数看做一个二进制序列,这样每一位都是布尔类型了。由于每一位之间时完全独立的,我们就可以通过一个循环,每次只对一位执行2-SAT,而不必同时把所有位都放到一张图中(如果这样做会MLE)。然后如果每次2-SAT都有解,那么整个矩阵有解。
附上一张从大佬的博客截过来的2-SAT逻辑运算转化表:
AC代码:
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#include <stack>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <map>
#include <string>
#include <set>
using namespace std;
#define INF 0x3f3f3f3f
#define LL long long
#define fi first
#define se second
#define mem(a,b) memset((a),(b),sizeof(a))
#pragma #pragma comment(linker, "/STACK:1024000000,1024000000")
const int MAXN=500+3;
const int MAXV=MAXN*2;
int N,V;
vector<int> G[MAXV],rG[MAXV];
vector<int> vs;
int save[MAXN][MAXN];
bool used[MAXV];
int cmp[MAXV];
void init()//初始化
{
for(int i=0;i<2*N;++i)
{
G[i].clear();
rG[i].clear();
}
}
void dfs(int v)//正向dfs
{
used[v]=true;
for(int i=0;i<G[v].size();++i)
if(!used[G[v][i]])
dfs(G[v][i]);
vs.push_back(v);
}
void rdfs(int v,int k)//反向dfs
{
used[v]=true;
cmp[v]=k;
for(int i=0;i<rG[v].size();++i)
if(!used[rG[v][i]])
rdfs(rG[v][i],k);
}
int scc()//Kosaraju算法求强连通分量
{
mem(used,0);
vs.clear();
for(int v=0;v<V;++v)
if(!used[v])
dfs(v);
mem(used,0);
int k=0;
for(int i=vs.size()-1;i>=0;--i)
if(!used[vs[i]])
rdfs(vs[i],k++);
return k;
}
int main()
{
while(~scanf("%d",&N))
{
bool ans=true;
for(int i=0;i<N;++i)
for(int j=0;j<N;++j)
{
scanf("%d",&save[i][j]);
if(i==j&&save[i][j]!=0)
ans=false;
if(i>j&&save[i][j]!=save[j][i])
ans=false;
}
V=N*2;
for(int i=0;i<32;++i)//每一位分开处理
{
init();
bool ok=true;
for(int i=0;i<N;++i)
for(int j=i+1;j<N;++j)
{
if((i&1)&&(j&1))//or
{
if(save[i][j]&1)
{
G[i+N].push_back(j);
G[j+N].push_back(i);
rG[j].push_back(i+N);
rG[i].push_back(j+N);
}
else
{
G[i].push_back(i+N);
G[j].push_back(j+N);
rG[i+N].push_back(i);
rG[j+N].push_back(j);
}
}
else if(i%2==0&&j%2==0)//and
{
if(save[i][j]&1)
{
G[i+N].push_back(i);
G[j+N].push_back(j);
rG[i].push_back(i+N);
rG[j].push_back(j+N);
}
else
{
G[i].push_back(j+N);
G[j].push_back(i+N);
rG[j+N].push_back(i);
rG[i+N].push_back(j);
}
}
else//xor
{
if(save[i][j]&1)
{
G[i].push_back(j+N);
G[j+N].push_back(i);
G[i+N].push_back(j);
G[j].push_back(i+N);
rG[j+N].push_back(i);
rG[i].push_back(j+N);
rG[j].push_back(i+N);
rG[i+N].push_back(j);
}
else
{
G[i].push_back(j);
G[j].push_back(i);
G[i+N].push_back(j+N);
G[j+N].push_back(i+N);
rG[j].push_back(i);
rG[i].push_back(j);
rG[j+N].push_back(i+N);
rG[i+N].push_back(j+N);
}
}
}
scc();
for(int i=0;i<N;++i)
if(cmp[i]==cmp[i+N])
{
ok=false;
break;
}
if(!ok)
{
ans=false;
break;
}
for(int i=0;i<N;++i)
for(int j=0;j<N;++j)
save[i][j]>>=1;
}
puts(ans?"YES":"NO");
}
return 0;
}