zoukankan      html  css  js  c++  java
  • Acwing 208.开关问题

    题意:

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

    思路:

    首先,我们要明确,我们只需要使起始状态和目标状态不同的开关发生变化。

    其次,注意操作开关$x$,开关$y$的状态也会发生改变。即开关$y$会因为开关$x$发生改变,所以$a[y][x] = 1$;不要忘记操作开关$x$本身,$x$的状态会发生变化,即$a[x][x] = 1$ 。

    最后,如果出现$0 =$非零,则无解,否则,答案为$2^k$, $k$为自由变量的数量

    Code:

    #pragma GCC optimize(3)
    #pragma GCC optimize(2)
    #include <map>
    #include <set>
    // #include <array>
    #include <queue>
    #include <stack>
    #include <vector>
    #include <cstdio>
    #include <cstring>
    #include <sstream>
    #include <iostream>
    #include <stdlib.h>
    #include <algorithm>
    // #include <unordered_map>
    
    using namespace std;
    
    typedef long long ll;
    typedef pair<int, int> PII;
    
    #define Time (double)clock() / CLOCKS_PER_SEC
    
    #define sd(a) scanf("%d", &a)
    #define sdd(a, b) scanf("%d%d", &a, &b)
    #define slld(a) scanf("%lld", &a)
    #define slldd(a, b) scanf("%lld%lld", &a, &b)
    
    const int N = 100 + 20;
    const int M = 1e2 + 20;
    const int mod = 1e9 + 7;
    
    int n;
    int st[N], en[N];
    int a[N][N];
    
    int gauss(){
        int r, c;
        for(r = 1, c = 1; c <= n; c ++){
            int t = r;
            for(int i = r + 1; i <= n; i ++){
                if(a[i][c]){
                    t = i;
                    break;
                }
            }
            if(!a[t][c]) continue;
            for(int i = c; i <= n + 1; i ++){
                swap(a[t][i], a[r][i]);
            }
            for(int i = r + 1; i <= n; i ++){
                if(a[i][c]){
                    for(int j = n + 1; j >= c; j --){
                        a[i][j] ^= a[r][j];
                    }
                }
            }
            r ++;
        }
    
        int res = 1;
        if(r < n + 1){
            for(int i = r; i <= n; i ++){
                if(a[i][n + 1]) return -1;
                res *= 2;
            }
        }
        return res;
    }
    
    void solve()
    {
        sd(n);
    
        for(int i = 1; i <= n; i ++){
            sd(st[i]);
        }
        for(int i = 1; i <= n; i ++){
            sd(en[i]);
        }
    
        for(int i = 1; i <= n; i ++){
            for(int j = 1; j <= n + 1; j ++){
                a[i][j] = 0;
            }
        }
    
        for(int i = 1; i <= n; i ++){
            a[i][i] = 1;
            a[i][n + 1] = (st[i] != en[i]);
        }
    
        int x, y;
    
        while(sdd(x, y), x || y){
            a[y][x] = 1;
        }
    
        int ans = gauss();
    
        if(ans == -1){
            puts("Oh,it's impossible~!!");
        }
        else{
            printf("%d
    ", ans);
        }
        
    }
    
    int main()
    {
    #ifdef ONLINE_JUDGE
    #else
        freopen("/home/jungu/code/in.txt", "r", stdin);
        // freopen("/home/jungu/code/out.txt", "w", stdout);
        // freopen("/home/jungu/code/out.txt","w",stdout);
    #endif
        // ios::sync_with_stdio(false);
        cin.tie(0), cout.tie(0);
    
        int T = 1;
        sd(T);
        // init();
        // int cas = 1;
        while (T--)
        {
            // printf("Case #%d:", cas++);
            solve();
        }
    
        return 0;
    }
  • 相关阅读:
    FHS Filesystem Hierarchy Standard(文件系统层次化标准)
    Linux文件类型
    cd、rm、ls命令
    基础内容
    Linux命令格式及使用方法
    Linux一些概念
    SHELL脚本的成分
    SHELL脚本
    Loadrunner关联
    赋值语句
  • 原文地址:https://www.cnblogs.com/jungu/p/13454157.html
Copyright © 2011-2022 走看看