zoukankan      html  css  js  c++  java
  • poj 1830 高斯消元

    开关问题
    Time Limit: 1000MS   Memory Limit: 30000K
    Total Submissions: 7033   Accepted: 2713

    Description

    有N个相同的开关,每个开关都与某些开关有着联系,每当你打开或者关闭某个开关的时候,其他的与此开关相关联的开关也会相应地发生变化,即这些相联系的开关的状态如果原来为开就变为关,如果为关就变为开。你的目标是经过若干次开关操作后使得最后N个开关达到一个特定的状态。对于任意一个开关,最多只能进行一次开关操作。你的任务是,计算有多少种可以达到指定状态的方法。(不计开关操作的顺序)

    Input

    输入第一行有一个数K,表示以下有K组测试数据。 
    每组测试数据的格式如下: 
    第一行 一个数N(0 < N < 29) 
    第二行 N个0或者1的数,表示开始时N个开关状态。 
    第三行 N个0或者1的数,表示操作结束后N个开关的状态。 
    接下来 每行两个数I J,表示如果操作第 I 个开关,第J个开关的状态也会变化。每组数据以 0 0 结束。 

    Output

    如果有可行方法,输出总数,否则输出“Oh,it's impossible~!!” 不包括引号

    Sample Input

    2
    3
    0 0 0
    1 1 1
    1 2
    1 3
    2 1
    2 3
    3 1
    3 2
    0 0
    3
    0 0 0
    1 0 1
    1 2
    2 1
    0 0
    

    Sample Output

    4
    Oh,it's impossible~!!
    

    Hint

    第一组数据的说明: 
    一共以下四种方法: 
    操作开关1 
    操作开关2 
    操作开关3 
    操作开关1、2、3 (不记顺序) 

    Source

    题意:我们可以看成每个开关与多个开关有关系,于是成了多元一次方程组问题,问的是有多少种方案,于是求出自由变元的个数,每个变元只有1,0两种选择,1<<x


    /*
    poj 1830 求解一元开关问题   
    */
    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    typedef long long ll;
    typedef long double ld;
    
    using namespace std;
    const int maxn = 200;
    
    int equ,var;
    int a[maxn][maxn];
    int x[maxn];
    int free_x[maxn];
    int free_num;
    
    int Gauss(int n)
    {
        equ = n; var = n;
        int max_r,col,k;
        free_num = 0;
        for(k = 0,col = 0; k < equ && col < var; k++,col++)
        {
            max_r = k;
            for(int i = k+1; i < equ; i++)
            {
                if(abs(a[i][col]) > abs(a[max_r][col]))
                    max_r = i;
            }
            if(a[max_r][col] == 0)
            {
                k --;
                free_x[free_num++] = col;
                continue;
            }
            if(max_r != k)
            {
                for(int j = col; j < var+1; j++)
                    swap(a[k][j],a[max_r][j]);
    
            }
            for(int i = k + 1; i < equ; i++)
            {
                if(a[i][col] != 0)
                {
                    for(int j = col; j < var+1; j++)
                        a[i][j] ^= a[k][j];
                }
            }
    
        }
        for(int i = k; i < equ; i++)
            if(a[i][col] != 0)
                return -1;
        if(k < var) return var-k;
    
        for(int i = var-1; i >= 0; i--)
        {
            x[i] = a[i][var];
            for(int j = i +1; j < var; j++)
                x[i] ^= (a[i][j] && x[j]);
    
        }
        return 0;
    
    }
    void ini()
    {
        memset(a,0,sizeof(a));
        memset(x,0,sizeof(x));
    }
    
    int start[maxn],End[maxn];
    
    int main()
    {
        int T;
        int n;
        scanf("%d",&T);
        while(T--)
        {
            ini();
            scanf("%d",&n);
            for(int i = 0; i < n; i++)
                scanf("%d",&start[i]);
            for(int i = 0; i < n; i++)
                scanf("%d",&End[i]);
    
            for(int i = 0; i < n; i++)
                a[i][i] = 1;
            int x,y;
            while(scanf("%d%d",&x,&y) && x && y)
            {
                a[y-1][x-1] = 1;
            }
            for(int i = 0; i < n; i++)
                a[i][n] = start[i]^End[i];
            int t = Gauss(n);
            if(t == -1)
                printf("Oh,it's impossible~!!
    ");
            else
                printf("%d
    ",1<<t);
        }
    }


  • 相关阅读:
    15、编写ORM
    14、细说协程
    COOKIE欺骗
    聪明的小羊
    re.S函数 python3
    截断上传
    sql百态01-post
    Why not?
    随机字符的本地爆破
    HTTP协议-请求头,响应头
  • 原文地址:https://www.cnblogs.com/Przz/p/5409646.html
Copyright © 2011-2022 走看看