• SGU 260.Puzzle (异或高斯消元)


    题意:

      有n(<200)个格子,只有黑白两种颜色.可以通过操作一个格子改变它和其它一些格子的颜色。给出改变的关系和n个格子的初始颜色,输出一种操作方案使所有格子的颜色相同。


    Solution:

      很显然的高斯消元。

          这里采用了类似SGU275的方法做。 

    /*
           解异或方程组
    */
    #include <iostream>
    #include <bitset>
    #include <cstring>
    using namespace std;
    const int N = 209;
    bitset<N> a[N], mask[N];
    int base[N];
    int Gauss ( int n )
    {
        for ( int i = 1; i <= n; ++i ) {
            for ( int j = 1; j <= n; ++j ) {
                if ( a[i][j] ) {
                    if ( !~base[j] ) {
                        mask[i][i] = 1;
                        base[j] = i;
                        break;
                    }
                    a[i] ^= a[base[j]];
                    mask[i] ^= mask[base[j]];
                }
            }
        }
    }
    
    int n, m;
    int main()
    {
        ios::sync_with_stdio ( 0 );
        cin >> n;
        for ( int i = 1, k; i <= n; ++i ) {
            cin >> k;
            for ( int j = 1, t; j <= k; ++j ) {
                cin >> t;
                a[i][t] = 1;
            }
        }
        memset ( base, -1, sizeof base );
        Gauss ( n );
        for ( int i = 1, k; i <= n; ++i ) {
            cin >> k;
            a[n + 1][i] = k;
            a[n + 2][i] = k ^ 1;
        }
        int k;
        for ( k = 1; k <= n; ++k ) {
            if ( a[n + 1][k] == 1 ) {
                if ( !~base[k] ) {
                    break;
                }
                a[n + 1] ^= a[base[k]];
                mask[n + 1] ^= mask[base[k]];
            }
        }
        if ( k > n ) {
            cout << mask[n + 1].count() << endl;
            for ( int i = 1; i <= n; ++i ) {
                if ( mask[n + 1][i] )
                    cout << i << " ";
            }
        } else {
            for ( k = 1; k <= n; ++k ) {
                if ( a[n + 2][k] ) {
                    if ( !~base[k] ) {
                        break;
                    }
                    a[n + 2] ^= a[base[k]];
                    mask[n + 2] ^= mask[base[k]];
                }
            }
            if ( k > n ) {
                cout << mask[n + 2].count() << endl;
                for ( int i = 1; i <= n; ++i ) {
                    if ( mask[n + 2][i] )
                        cout << i << " ";
                }
            } else {
                cout << -1 << endl;
            }
        }
    }
    View Code
  • 相关阅读:
    概要设计
    JNI内存泄露
    Flash 与 JS 交互
    Lucene.net 实现全文搜索(转)
    自动打开登录游戏的代码
    Ajax,网站改版的一种方法
    IE6/IE7和Firefox对Div处理的差异(转)
    搜VC里找到的
    C# 尝试读取或写入受保护的内存。这通常指示其他内存已损坏
    HTML特殊转义字符列表
  • 原文地址:https://www.cnblogs.com/keam37/p/4659481.html
Copyright © 2020-2023  润新知