• POJ


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

    sol:即求自由元的个数,答案是pow(2,自由元)。

    #include<bits/stdc++.h>
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    using namespace std;
    int a[30][30],ans[30];
    int Guass(int N)
    {
        int res=0;
        rep(i,0,N-1){
            int mark=i;
            rep(j,i+1,N-1) if(abs(a[j][i])>abs(a[mark][i])) mark=j;
            if(mark!=i) rep(j,0,N) swap(a[i][j],a[mark][j]);
            if(!a[i][i]){ res++; continue;} //自由元
            rep(j,i+1,N){
               if(!a[j][i]) continue;
               rep(k,i,N){
                   a[j][k]^=a[i][k];
               }
            }
        }
        for(int i=N-1;i>=0;i--){
            if(!a[i][i]&&a[i][N]) return -1;//无解
            ans[i]=a[i][N]&a[i][i];
            rep(j,0,i-1) a[j][N]^=(a[j][i]&ans[i]);
        }
        return 1<<res;
    }
    int s[300],t[300],res;
    int main()
    {
        int T,N,u,v;
        scanf("%d",&T);
        while(T--){
            memset(a,0,sizeof(a));
            scanf("%d",&N);
            rep(i,0,N-1) scanf("%d",&s[i]);
            rep(i,0,N-1) scanf("%d",&t[i]);
            rep(i,0,N-1) a[i][N]=s[i]^t[i],a[i][i]=1;
            while(~scanf("%d%d",&u,&v)&&u+v!=0){
                a[v-1][u-1]=1; //二者不要写反
            }
            int res=Guass(N);
            if(res==-1) puts("Oh,it's impossible~!!");
            else printf("%d
    ",res);
        }
        return 0;
    }
  • 相关阅读:
    MySQL InnoDB 存储引擎探秘
    MySQL优化面试
    技术面试老是有劲使不出,该怎么办?
    详解RPC远程调用和消息队列MQ的区别
    ConcurrentHashMap1.8源码分析
    kafka topic制定规则
    GitLab本地、远程更新已经fork的项目
    Swagger2使用参考
    分布式配置中心选型
    搭建Elasticsearch平台
  • 原文地址:https://www.cnblogs.com/hua-dong/p/10764284.html
Copyright © 2020-2023  润新知