• 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 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?
     
    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)
     
    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

    two-sat ,果然考的就是构图 。。。 

    那些边的数量不好估计空间大小, 所以还是用stl 来构边好了 。 。

    然后对于 two-sat .. 特别喜欢构反向边 ..不知道这个是不是好习惯。 。

    讲回这题。 。

    分3种运算,

    1 。 | (或运算符) ....

         a. 若 b[i][j] 的二进制第大k位为 0 的时候  , a[i] , a[j]只能为 0 了 。

         b. 否则 ,  a[i] , a[j]不能同为 0  。

    2 。 & (与运算符) ...

         a. 若 b[i][j] 的二进制第大k位为 1 的时候  , a[i] , a[j]只能为 1 了 。

         b. 否则 ,  a[i] , a[j]不能同为 1 。

    3。 ^(异或运算符)...

         a. 若 b[i][j] 的二进制第大k位为 0 的时候  , a[i] , a[j]只能相同 了 。

         b. 否则 ,  a[i] , a[j] 不能相同。

    按照上面的规则构图就行了 。。

    然后再进行two-sat的时候 , 要对B数组先检测一下

    是否符合     1.( i == j && B[i][j] == 0 )

                    2.( i != j && B[i][j] == B[j][i] )

    一开始构图构蒙了,连这个也没判。 值得WA了 。 

    最后 , 就是对二进制位, 每一个位(位与位之间不存在关系)判一次 two-sat 

    一开始 ,全部弄一起判,边所用的空间太恐怖了 ~~MLE 了

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <iostream>
    #include <vector>
    
    using namespace std;
    const int N = 550 ;
    int n ;
    
    int B[N][N];
    vector<int>g[N<<1];
    int st[N<<2] , top ;
    bool mark[N<<2];
    
    void init()
    {
        for( int i = 0; i < 2 * n ; ++i ) g[i].clear();
        memset( mark ,false, sizeof mark );
    }
    
    void addedge( int u , int v )
    {
        g[u].push_back(v) , g[v].push_back(u);
    }
    
    bool dfs( int u )
    {
        if( mark[u] ) return true;
        if( mark[u^1] ) return false;
        mark[u] = true;
        st[ top++ ] = u ;
        for( int i = 0 ; i < g[u].size(); ++i ){
            int v = g[u][i];
            if( !dfs( v^1 ) ) return false;
        }
        return true;
    }
    
    
    bool solve()
    {
        for( int i = 0 ; i < 2 * n ; i += 2 ){
            if( !mark[i] && !mark[i+1] ){
                top = 0 ;
                if( !dfs(i) ){
                    while( top > 0 ) mark[ st[--top] ] = false;
                    if( !dfs( i+1 ) ) return false;
                }
            }
        }
        return true;
    }
    
    bool check()
    {
        for( int i = 0 ; i< n ; ++i ){
            for( int j = i ; j < n ; ++j ){
                if( i == j && B[i][j] != 0 )return false ;
                else if( i != j && B[i][j] != B[j][i] ) return false;
            }
        }
        return true;
    }
    
    void run()
    {
        for( int i = 0 ; i < n ; ++i ){
            for( int j = 0 ; j < n ; ++j ){
                scanf("%d",&B[i][j]);
            }
        }
        if( !check() ) { puts("NO"); return ; }
    
        for( int k = 0 ; k < 31 ; ++k ){
            init();
            for( int i = 0 ; i < n ; ++i ){
                for( int j = i + 1 ; j < n ; ++j ){
                    if( ( i % 2 == 1 ) && ( j % 2  == 1 ) ){          //        |
                        if( ( B[i][j]&(1<<k) ) ){
                            addedge( 2*i^1 ,2*j^1 );
                        }
                        else{
                            addedge( 2*i ,2*j^1 );
                            addedge( 2*i ,2*j );
                            addedge( 2*i^1 , 2*j );
                        }
                }
                else if( ( i % 2 == 0 )&& ( j % 2 == 0 ) ) {     //        &
                        if( ( B[i][j]&(1<<k)) == 0  ){
                            addedge( 2*i ,2*j );
                        }
                        else {
                            addedge( 2*i^1 ,2*j^1 );
                            addedge( 2*i^1 ,2*j );
                            addedge( 2*i , 2*j^1 );
                        }
                }
                else {                                    //         ^
                        if( ( B[i][j] & ( 1<< k) ) != 0 ){
                            addedge( 2*i ,2*j );
                            addedge( 2*i^1 ,2*j^1 );
                        }
                        else {
                            addedge( 2*i^1 ,2*j );
                            addedge( 2*i,2*j^1 );
                        }
                    }
                }
            }
            if( !solve() ) {  puts("NO");  return ;  }
        }
        puts("YES");
    }
    
    int main()
    {
        #ifdef LOCAL
            freopen("in.txt","r",stdin);
        #endif // LOCAL
        while( ~scanf("%d",&n) ) run();
    }
    only strive for your goal , can you make your dream come true ?
  • 相关阅读:
    利用html2canvas将html页面截图 js
    微信网页分享功能 js
    json数组排序 js
    数字千位符 js
    调用百度Api读取图片文字 C#
    判断手机移动端js
    网页添加水印js
    css 文字隐藏,鼠标移动显示
    删除某个数据库下所有表
    linux错误记录
  • 原文地址:https://www.cnblogs.com/hlmark/p/4028885.html
Copyright © 2020-2023  润新知