• P4906 小奔关闹钟


    题目背景

    由于今天是星期一,闹钟准时响了,由于小奔太困了,所以她想关停闹钟。

    题目描述

    可是,他的闹钟电路太复杂了,有很多个开关,每个开关都连着其他开关,其他开关又连着更多的开关,当且仅当所有开关都关闭时,闹钟才会停止响铃,(初始时默认每个开关都开着的),她该如何是好呢?

    请你帮小奔求出最少开关次数,如果无论如何都不能关闭闹钟,请输出‘Change an alarm clock,please!’

    输入输出格式

    输入格式:

    共有N+1行

    第一行一个数N(1≤N≤20),表示有N个开关,从第2行起的第i行表示第i个闹钟开关。

    以后N行,每行第一个数为M(0≤M≤N-1),表示第i个闹钟开关的直接关联开关个数。(由直接关联开关所关联的直接关联开关,自然就是第i个闹钟间接关联开关啦,当打开第i个开关时,只有直接关联,间接关联以及第i个开关才会起作用。),之后M个数,表示第i个闹钟直接关联开关的标号。(如果M为0则表示没有任何关联)

    输出格式:

    一个数ans,表示最少按开关次数,如果无法关闭,输出‘Change an alarm clock,please!’

    输入输出样例

    输入样例#1: 复制

    5
    4 2 3 4 5
    2 1 3
    2 1 4
    2 1 5
    1 1

    输出样例#1: 复制

    2

    说明

    样例1说明:

    先关闭5,直接关联会关闭1。1间接关闭2、3、4,但会重新打开5。

    此时共关闭开关一次,已关闭1,2,3,4

    再打开2,直接关联会打开1和3。1间接关闭2、3、5,重新打开4。3间接关闭1、4。

    此时共关闭开关2次,已关闭1,2,3,4,5,彻底关闭闹钟。


    sb题+卡读入==黑体????
    enter image description here


    二进制状压,预处理按每一种开关后的情况bfs搜索情况0即可


    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<queue>
    #define LL long long
    #define max(a,b) ((a)>(b)? (a):(b))
    #define min(a,b) ((a)<(b)? (a):(b))
    
    using namespace std;
    
    int b[5000000],i,m,n,j,k,a[25],d[25],bl[21][21],x;
    queue <int>q;
    
    void bfs()
    {
        b[(1<<n)-1]=1;
        q.push((1<<n)-1);
        while(q.size())
        {
            int t=q.front(); q.pop();
            for(int i=1;i<=n;i++) 
            {
                if(!b[t^d[i]]) 
                {
                    b[t^d[i]]=b[t]+1;
                    q.push(t^d[i]);
                }
            }
            if(b[0]) return;
        }
    }
     
    int main()
    {
        scanf("%d",&n);
        for(i=1;i<=n;i++) 
        {
            memset(b,0,sizeof(b));
            b[i]=1;
            scanf("%d",&m);
            for(j=1;j<=m;++j)
            {
                scanf("%d",&x);
                bl[i][x]=1;
            }
        }
        for(i=1;i<=n;++i)
        {
            d[i]^=(1<<(i-1));
            for(j=1;j<=n;++j) if(bl[i][j] && i != j)
            {
                d[i]^=(1<<(j-1));
                for(k = 1; k <= n; ++k) if(bl[j][k] && k != j)
                    d[i]^=(1<<(k-1));
            }
        }
        bfs();
        if(b[0]==0) printf("Change an alarm clock,please!");
        else printf("%d",b[0]-1);
    }
    
  • 相关阅读:
    Android常用URI收藏
    2017 ZSTU寒假排位赛 #3
    HDU 3689 Infinite monkey theorem ——(自动机+DP)
    CodeForces 755D PolandBall and Polygon ——(xjbg)
    2017 ZSTU寒假排位赛 #2
    HDU 3264 Open-air shopping malls ——(二分+圆交)
    HDU 1255 覆盖的面积 ——(线段树+扫描线)
    HDU 3265 Posters ——(线段树+扫描线)
    2017 ZSTU寒假排位赛 #1
    UVA 11853 Paintball ——(dfs+圆交判定)
  • 原文地址:https://www.cnblogs.com/ZUTTER/p/9866955.html
Copyright © 2020-2023  润新知