• Switches( 位运算 )


    思路:

    • 亮着的灯就是 1,反之 是 0, 把开关所连接的灯泡当成 二进制数 (例如011011,有连接就是1)通过异或运算看看有没有 初式 二进制数相等的,
    • 最多做2n, 因为 2n 后 dp值就是0了, (看2n前有没有答案);

    小技巧:

    • 位运算 满足集合率和交换律(所有运算都是同一种时)
    • & : 看 有没有0;有0就是0;
    • ^:    看 1的奇偶个数;
    • |  : 看有没有1;有1 就是1 ;
    In the control panel of an enormous amphitheatre, there are NN switches, numbered from 1 to NN, that control the MM light bulbs of the place, which are numbered from 1 to MM. Note that the number of switches and light bulbs is not necessarily the same and this happens because each switch is associated not to a single light bulb, but to a set of light bulbs. When a switch is activated, each one of the bulbs associated to it is toggled. If the bulb is lit, then it will be switched off, otherwise it will be switched on.
    
    Some bulbs are lit initially and the janitor in charge of the amphitheatre has to switch off all them. He started trying to press the switches randomly, but as soon as he figured out that it wouldn't necessarily work, he decided to follow a fixed strategy. He will trigger the switches 1, 2, 3, \dots, N, 1, 2, 3, \dots1,2,3,…,N,1,2,3,… in other words, every time after triggering the switch number NN, he resumes the procedure from the switch number 1. He intends to keep pressing switches by the given strategy until all bulbs are switched off at the same time (in that moment he stops pressing the switches). Will his strategy work?
    
    Given the bulbs which are initially lit and the sets of lamps associated to each switch, your program should compute the number of times the janitor will press switches. If by following the given strategy the janitor is never able to switch off all the lamps at the same time, your program should print -1.
    
    Input
    The first line contains two integers NN and MM (1 \leq N, M \leq 10001≤N,M≤1000) representing, respectively, the number of switches and the number of light bulbs. The second line contains an integer LL (1 \leq L \leq M1≤L≤M) followed by distinct integers X_iX 
    i
    ​
      (1 \leq X_i \leq M1≤X 
    i
    ​
     ≤M), representing the bulbs that are lit in the first place. Each of the following NN rows contains an integer K_iK 
    i
    ​
      (1 \leq K_i \leq M1≤K 
    i
    ​
     ≤M) followed by K_iK 
    i
    ​
      distinct integers Y_iY 
    i
    ​
      (1 \leq Y_i \leq M1≤Y 
    i
    ​
     ≤M), representing the bulbs attached to switch ii (1 \leq i \leq N1≤i≤N).
    
    Output
    Your program must print a single line containing an integer representing the number of times the janitor will press the switches by following the strategy described, until all the lights were off at the same time. If that never happens, print -1.
    
    Sample 1
    Inputcopy    Outputcopy
    6 3
    2 1 3
    3 1 2 3
    2 1 3
    2 1 2
    2 2 3
    1 2
    3 1 2 3
    View problem
    #include <bits/stdc++.h>
    using namespace std;
    #define ri register int 
    #define  M 1005
    
    template <class G > void read(G &x)
    {
        x=0;int f=0;char ch=getchar();
        while(ch<'0'||ch>'9'){f|=ch=='-';ch=getchar();}
        while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
        x=f?-x:x;
        return ;
    }
    
    int arr[M][M];
    int p[M],flag[M],cur,dp[M],ans=0;
    int n,m,L;
    
    int main(){
        
        read(n);read(m);read(L);
        for(ri i=1;i<=L;i++)
        {
            int a;
            read(a);p[a]=1;
        }
        
        for(ri i=1;i<=n;i++)
        {
            int k=0;
            read(k);
            for(ri j=1;j<=k;j++)
            {
                int a;read(a);
                arr[i][a]=1;
            }
            for(ri j=1;j<=m;j++)
            {
                dp[j]=dp[j]^arr[i][j];
                if(dp[j]==p[j])
                {
                    if(flag[j]) continue;
                    flag[j]=1;cur++;
                }
                else
                {
                    if(flag[j]==0) continue;
                    flag[j]=0;cur--;
                }
            }
            if(cur==m)
            {
                ans=i;break;
            }
        }
        if(ans){
            printf("%d",ans);return 0;
        }
        for(ri i=1;i<=n;i++)
        {
            for(ri j=1;j<=m;j++)
            {
                dp[j]=dp[j]^arr[i][j];
                if(dp[j]==p[j])
                {
                    if(flag[j]) continue;
                    flag[j]=1;cur++;
                }
                else
                {
                    if(flag[j]==0) continue;
                    flag[j]=0;cur--;
                }
            }
            if(cur==m)
            {
                ans=i+n;break;
            }
        }
    
       if(ans) printf("%d",ans);
       else printf("-1");
       return 0;
        
    } 
    View Code
  • 相关阅读:
    webstorm
    数据库中的内连接和外连接
    JVM加载class文件的原理机制
    内部类
    getString()方法与getObject()方法的区别
    Class.forName的作用
    JDBC事务处理
    合并两个排序的链表
    链表中倒数第k个结点
    反转链表
  • 原文地址:https://www.cnblogs.com/Lamboofhome/p/16134232.html
Copyright © 2020-2023  润新知