Bit Magic HDU - 4421

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?

InputThere 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)

OutputFor 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
  1 // ConsoleApplication2.cpp: 定义控制台应用程序的入口点。
  2 //
  3
  4 // ConsoleApplication1.cpp: 定义控制台应用程序的入口点。
  5 //
  6
  7 #include "stdafx.h"
  8 #include<stack>
  9 #include<cstdio>
 10 #include<cstring>
 11 #include<iostream>
 12 #include<algorithm>
 13 #define mem(array) memset(array,0,sizeof(array))
 14 using namespace std;
 15
 16 const int maxn = 6000;
 17 const int maxm = 999999;
 18
 19 stack<int> S;
 20
 21 struct node {
 22     int to, next;
 23 }e[maxm];
 24
 25 int k, n, tot, index;
 26 int Low[maxn], Dfn[maxn], head[maxn], cmp[maxn],map[505][505];
 27 bool use[maxn];
 28
 29 void Inite() {
 30     k = tot = index = 0;
 31     mem(Dfn); mem(use); mem(cmp);
 32     memset(head, -1, sizeof(head));
 33 }
 34
 35 void addedge(int u, int v) {
 36     e[tot].to = v;
 37     e[tot].next = head[u];
 38     head[u] = tot++;
 39 }
 40
 41 void Tarjan(int u) {
 42     Low[u] = Dfn[u] = ++index;
 43     S.push(u);
 44     use[u] = 1;
 45     for (int i = head[u]; i != -1; i = e[i].next) {
 46         int v = e[i].to;
 47         if (!Dfn[v]) {
 48             Tarjan(v);
 49             Low[u] = min(Low[u], Low[v]);
 50         }
 51         else if (use[v]) {
 52             Low[u] = min(Low[u], Dfn[v]);
 53         }
 54     }
 55     int v;
 56     if (Dfn[u] == Low[u]) {
 57         k++;
 58         do {
 59             v = S.top();
 60             S.pop();
 61             cmp[v] = k;
 62             use[v] = 0;
 63         } while (v != u);
 64     }
 65 }
 66
 67 bool check() {
 68     for (int i = 0; i < n; i++) {
 69         if (map[i][i]) return false;
 70         for (int j = i + 1; j < n; j++)
 71             if (map[i][j] != map[j][i]) return false;
 72     }
 73     return true;
 74 }
 75
 76 int main()
 77 {
 78     while (scanf_s("%d", &n) != EOF) {
 79         for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) scanf_s("%d", &map[i][j]);
 80         if (!check()) { puts("NO"); continue; }
 81         bool flag = false;
 82         for (int p = 0; p < 31; p++) {
 83             Inite();
 84             for (int i = 0; i < n; i++) {
 85                 for (int j = i + 1; j < n; j++) {
 86                     if (i % 2 == 1 && j % 2 == 1) {
 87                         if ((map[i][j] >> p) & 1) {
 88                             addedge(i + n, j);
 89                             addedge(j + n, i);
 90                         }
 91                         else {
 92                             addedge(i, i + n);
 93                             addedge(j, j + n);
 94                         }
 95                     }
 96                     else if (i % 2 == 0 && j % 2 == 0) {
 97                         if ((map[i][j] >> p) & 1) {
 98                             addedge(i + n, i);
 99                             addedge(j + n, j);
100                         }
101                         else {
102                             addedge(i, j + n);
103                             addedge(j, i + n);
104                         }
105                     }
106                     else {
107                         if ((map[i][j] >> p) & 1) {
108                             addedge(i, j + n);
109                             addedge(i + n, j);
110                             addedge(j, i + n);
111                             addedge(j + n, i);
112                         }
113                         else {
114                             addedge(i, j);
115                             addedge(j, i);
116                             addedge(i + n, j + n);
117                             addedge(j + n, i + n);
118                         }
119                     }
120                 }
121             }
122             for (int i = 0; i < 2 * n; i++) if (!Dfn[i]) Tarjan(i);
123             for (int i = 0; i < n; i++) if (cmp[i] == cmp[i + n]) flag = true;
124             if (flag) break;
125          }
126         if (flag) puts("NO");
127         else puts("YES");
128     }
129     return 0;
130 }
时间: 2024-11-02 23:00:46

Bit Magic HDU - 4421的相关文章

HDU 4421 Bit Magic(2-sat)

HDU 4421 Bit Magic 题目链接 题意:就依据题目,给定b数组.看能不能构造出一个符合的a数组 思路:把每一个数字的每一个二进制位单独考虑.就变成一个2-sat题目了,依据题目中的式子建立2-sat的边.然后每一位跑2-sat.假设每位都符合.就是YES,假设有一位不符合就是NO 代码: #include <cstdio> #include <cstring> #include <cstdlib> #include <vector> #incl

hdu 4421 BitMagic

这是一道区域赛的题目,解法有许多,这边是2-sat的做法 题目大意:自己看题 分析:对于A[i]的每一位做2-SAT,判断是否可行. 主要是建图: 对于a&b=0  有 a-> ┐b, b-> ┐a a&b=1            ┐a->a , ┐b->b a|b=0            a-> ┐a,b-> ┐b a|b=1     ┐a->b, ┐b->a a^b=0 a->b,b->a, ┐a-> ┐b, ┐b-

HDU 4421 Bit Magic(奇葩式解法)

题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=4421 题目大意: 给了你一段代码, 用一个数组的数 对其进行那段代码的处理,是可以得到一个矩阵 让你判断这个矩阵能否由一个数组转化而来. 思路: 既然每组数据可以得到,那么他肯定能消去. 我们用一个数组P[i][j] 保存 a[i]^a[j]   的值 a[i]^a[j] 我们可用 P[i][j] = P[i][j-1]^a[j-1]^a[j] 这样我们就可以找出所有 P[i][j] = a[i]^

图论(2-sat):HDU 4421 Bit Magic

Bit Magic Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3040    Accepted Submission(s): 871 Problem Description Yesterday, my teacher taught me about bit operators: and (&), or (|), xor (^). I

HDU 4421 Bit Magic (图论-2SAT)

Bit Magic 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 ac

hdu 4421 Bit Magic

Bit Magic Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2057    Accepted Submission(s): 590 Problem Description Yesterday, my teacher taught me about bit operators: and (&), or (|), xor (^). I

hdu 4421 和poj3678类似二级制操作(2-sat问题)

/* 题意:还是二进制异或,和poj3678类似 建边和poj3678一样 */ #include<stdio.h> #include<string.h> #include<math.h> #define N 2100 struct node{ int v,next; }bian[N*N]; int head[N],dfn[N],low[N],vis[N],stac[N],belong[N],yong,ans,index,top; void init() { yong=

【图论】2-sat总结

2-sat总结 2-sat问题,一般表现的形式为.每一个点有两种方式a,b,要么选a,要么选b.而且点点之间有一些约束关系.比如:u和v至少一个选a.那么这就是一个表达式.把a当成真,b当成假,那就是u真或v真.2-sat的题目就是这样.给定这些约束,推断是否会矛盾 注意表达式的转化形式,(事实上就是离散数学中那几种转换方式) 比方(u真且v真)或(u假且v假)就能够转化成(u真或v假)且(u假或v真),这样就能建立关系 2-sat中的原理,事实上和2染色是一样的,把每一个结点拆分成一个真结点和

【图论】

2-sat总结 2-sat问题,一般表现的形式为,每个点有两种方式a,b,要么选a,要么选b,并且点点之间有一些约束关系,例如:u和v至少一个选a,那么这就是一个表达式,把a当成真,b当成假,那就是u真或v真,2-sat的题目就是这样,给定这些约束,判断是否会矛盾 注意表达式的转化形式,(其实就是离散数学中那几种转换方式) 比如(u真且v真)或(u假且v假)就可以转化成(u真或v假)且(u假或v真),这样就能建立关系 2-sat中的原理,其实和2染色是一样的,把每个结点拆分成一个真结点和一个假结