题意:b[i][j] 与a[i], a[j]的关系如下。现在已知b,问是否存在对应的a,若存在输出YES,否则输出NO
void calculate(int a[N], int b[N][N]) { for (int i = 0; i < N; ++i) { for (int j = 0; j < N; ++j) { if (i == j) b[i][j] = 0; else if (i % 2 == 1 && j % 2 == 1) b[i][j] = a[i] | a[j]; else if (i % 2 == 0 && j % 2 == 0) b[i][j] = a[i] & a[j]; else b[i][j] = a[i] ^ a[j]; } } }
题解:
#include<cstring>
#include<algorithm>
#include <cstdio>
using namespace std;
#define MAXN 1010
int n;
unsigned int b[510][510];
int m[1010][1010];
int id[1010];
int find_components(int n,int mat[][MAXN],int* id){
int ret=0,a[MAXN],b[MAXN],c[MAXN],d[MAXN],i,j,k,t;
for (k=0;k<n;id[k++]=0);
for (k=0;k<n;k++)
if (!id[k]){
for (i=0;i<n;i++)
a[i]=b[i]=c[i]=d[i]=0;
a[k]=b[k]=1;
for (t=1;t;)
for (t=i=0;i<n;i++){
if (a[i]&&!c[i])
for (c[i]=t=1,j=0;j<n;j++)
if (mat[i][j]&&!a[j])
a[j]=1;
if (b[i]&&!d[i])
for (d[i]=t=1,j=0;j<n;j++)
if (mat[j][i]&&!b[j])
b[j]=1;
}
for (ret++,i=0;i<n;i++)
if (a[i]&b[i])
id[i]=ret;
}
return ret;
}
void build_map(int k)
{
memset(m, 0, sizeof(m));
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++)
{
if(i == j) continue;
if(i % 2 == 1 && j % 2 == 1)
{
if(b[i][j] & (1<<k))
{
m[i][j+n] = 1;
m[j][i+n] = 1;
}
else
{
m[i+n][i] = 1;
m[j+n][j] = 1;
}
}
else if(i % 2 == 0 && j % 2 == 0)
{
if(b[i][j] & (1<<k))
{
m[i][i+n] = 1;
m[j][j+n] = 1;
}
else
{
m[j+n][i] = 1;
m[i+n][j] = 1;
}
}
else
{
if(b[i][j] & (1<<k) )
{
m[i][j+n] = m[j+n][i] = 1;
m[j][i+n] = m[i+n][j] = 1;
}
else
{
m[i][j] = m[j][i] = 1;
m[i+n][j+n] = m[j+n][i+n] = 1;
}
}
}
}
void solve()
{
for(int k = 0; k < 32; k++)
{
build_map(k);
memset(id, 0, sizeof(id));
find_components(2*n, m, id);
for(int i = 0; i < n; i++)
if(id[i] == id[i+n])
{
printf("NO\n");
return;
}
}
printf("YES\n");
}
int main()
{
while(scanf("%d",&n) != EOF)
{
int i, j;
memset(id, 0, sizeof(id));
memset(b, 0, sizeof(b));
for(i = 0; i < n; i++)
for(j = 0; j < n; j++)
scanf("%d",&b[i][j]);
bool flag = true;
for(i = 0; i < n; i++)
if(b[i][i]) { flag = false; break; }
if(flag == false)
{
printf("NO\n");
continue;
}
solve();
}
return 0;
}