题意: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; }