zoukankan      html  css  js  c++  java
  • poj 2345 Central heating

     
    Central heating
    Time Limit: 1000MS   Memory Limit: 65536K
    Total Submissions: 703   Accepted: 321

    Description

    Winter has come, but at the Ural State University heating is not turned on yet. There's one little problem: the University is heated only if all of the valves are opened. There are some technicians at the University. Each of them is responsible for one or more valves. There may be several technicians responsible for the same valve. When a technician gets an instruction to turn on the heating he goes round all of his valves and turns them. It means that if a valve was opened then he closes it, and if it was closed then he opens it. It is well known that every technician earns his money not in vain so it's impossible to replace any technician by any combination of other technicians. 
    Your task is to determine who of the technicians is to get an instruction "to turn on the heating" in order to heat all the Ural State University. Note that there are N technicians and N valves at the University (1 <= N <= 250). 

    Input

    The first line of an input contains the number N. The next N lines contain lists of the valves in charge of each of the technicians. It means that a line number i + 1 contains numbers of the valves that the i-th technician is responsible for. Each list of valves is followed by –1.

    Output

    An output should contain a list of technicians' numbers sorted in ascending order. If several lists are possible, you should send to an output the shortest one. If it's impossible to turn on the heating at the University, you should write "No solution" .

    Sample Input

    4
    1 2 -1
    2 3 4 -1
    2 -1
    4 -1
    

    Sample Output

    1 2 3

    题意:
    n个人控制n台机器,并且有n个开关,每台机器都可以控制一部分开关的开和闭,并且任何一台机器的功能都不能被其余的机器所取代,最终要将n个开关都打开,问每台机器应该被操作几次
    思路:
    每个开关最终的结果要么是1(开),要么是0(闭),并且这个结果是由n台机器进行操作后得到,并且有一个事实,机器操作奇数次和操作一次的效果是一样的,操作偶数次和不操作是一样的,所以其实每台机器只有操作或者不操作两种情况。
    依据样例做一个解释:设4台机器分别操作x1,x2,x3,x4次,并且最终4个开关都要处于开的状态
    对于第一个开关(1,0,0,0)(x1)==1 对于第二个开关(1,1,1,0)(x1)==1 对于第三个开关(0,1,0,0)(x1)==1 对于第四个 (0,1,0,1)(x1)==1
    (x2) (x2) (x2) (x2)
    (x3) (x3) (x3) (x3)
    (x4) (x4) (x4) (x4)
    把上述方程合并成矩阵形式,gauss消元求解即可,只是原来的减法要改成异或运算,乘法要改成与运算即可

    其中(1,0,0,0),(1,1,1,0),(0,1,0,0),(0,1,0,1)线性无关,意味着一定会有解
    #define _CRT_SECURE_NO_DEPRECATE
    #include<iostream>
    #include<cstdio>
    #include<vector>
    #include<algorithm>
    #include<cstring>
    #include<set>
    #include<string>
    #include<queue>
    #include<cmath>
    #include<bitset>
    #include<map>
    using namespace std;
    #define INF 0x3f3f3f3f
    const double EPS = 1e-8;
    const int N_MAX = 250 + 16;
    typedef long long ll;
    typedef vector<int>vec;
    typedef vector<vec>mat;
    int n;
    
    vec gauss(const mat&A,const vec&b) {
        int n = A.size();//!!!!
        
        mat B(n, vec(n + 1));
        for (int i = 0; i < n; i++)
            for (int j = 0; j < n; j++)B[i][j] = A[i][j];
        for (int i = 0; i < n; i++)B[i][n] = b[i];
        for (int i = 0; i < n;i++) {
            int pivot = i;
            for (int j = i; j < n;j++) {
                if (B[j][i] > B[pivot][i]) {//!!!
                    pivot = j;
                }
            }
            swap(B[i],B[pivot]);
            if (B[i][i] < EPS)return vec();//无解,当然这题都有解
    
            for (int j = 0; j < n; j++) {
                if (i != j) {
                    for (int k = i + 1; k <= n; k++) {
                        B[j][k] ^=  B[j][i]&B[i][k];
                    }
                }
            }
        }
        vec x(n);
        for (int i = 0; i < n;i++) {
            x[i] = B[i][n];
        }
        return x;
    }
    
    int main() {   
        
        
        while (scanf("%d",&n)!=EOF) {
            vec b(n);
            for (int i = 0; i < n;i++) {//预处理
                b[i] = 1;
            }
            mat A(n, vec(n));
        
            for (int i = 0; i < n; i++) {
                while (1){
                    int a;
                    scanf("%d",&a);
                    if (a == -1)break;
                    a--;
                    A[a][i] = 1;
                }
            }
            vec x = gauss(A, b);
            
            bool flag = 0;
            for (int i = 0; i < x.size();i++) {
                if (x[i]) {
                    if (!flag) {
                        flag = 1;
                        printf("%d",i+1);
                    }
                    else {
                        printf(" %d",i+1);
                    }
                }
            }
            puts("");
    
        }
        return 0;
    }
  • 相关阅读:
    利用SQL注入漏洞登录后台
    http://www.cnblogs.com/xdp-gacl/p/4200090.html
    文件上传的三种模式-Java
    Maven多模块,Dubbo分布式服务框架,SpringMVC,前后端分离项目,基础搭建,搭建过程出现的问题
    win10 安装 mysql解压版安装步骤
    移动开发首页业界资讯移动应用平台技术专题 输入您要搜索的内容 基于Java Socket的自定义协议,实现Android与服务器的长连接(二)
    IEDA 启动main报 stock
    基于JavaMail的Java邮件发送:简单邮件发送
    如何确定一个需求是真需求
    VS中批注的使用
  • 原文地址:https://www.cnblogs.com/ZefengYao/p/7834540.html
Copyright © 2011-2022 走看看