• 【bitset模板题】HDU 5036 Explosion


    题意:
    一个人要打开或者用炸弹砸开所有的门,每个门里面有一些钥匙,一个钥匙对应一个门,有了一个门的钥匙就能打开相应的门,告诉每个门里面有哪些门的钥匙,问用的炸弹为期望值。
     
    分析:
    期望值 = 每个门用炸弹炸开的概率之和
    而 每个门用炸弹炸开的概率 = 1 / 到达这个门的方案数, 因为炸开门的方案只有一种
    我们用bitset记录门间的联通情况,求出方案数即可
     
    我们开一个bitset数组 a
           假如  a[i] = 0  1  0  1  1  0  1          即 i 号门能到 1 3 4 6 号门
                    a[j] = 1  0  0  1  0  1  0
    如果 j 能到 i ,那么 j 本来能到的现在还能到, i 能到的 j 也能到
    也就是我们把   a[j] |= a[i] 即可
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <bitset>
    using namespace std;
    const int maxn = 1005;
    bitset<maxn> a[maxn];
    int main() {
        int t; scanf("%d", &t);
        for(int cnt=1; cnt<=t; cnt++){
            int n; scanf("%d", &n);
            for(int i=0; i<n; i++){ 
                a[i].reset();       //这里记得初始化
                a[i][i] = 1;       //自己到自己是联通的
            }
            for(int i=0; i<n; i++){
                int k; scanf("%d", &k);
                while(k--){
                    int x; scanf("%d", &x);
                    a[i][--x] = 1;//我们的下标统一从0开始,所以 --x
                }
            }
            for(int i=0; i<n; i++){
                for(int j=0; j<n; j++){
                    if(a[j][i]) a[j] |= a[i]; //i能到达的j也能到达
                }
            }
            double ans = 0;
            int tot = 0;
            for(int i=0; i<n; i++){
                tot = 0;
                for(int j=0; j<n; j++){
                    if(a[j][i]) tot ++;//求方案数
                }
                ans += 1.0/tot; //更新期望值
            }
            printf("Case #%d: %.5lf
    ", cnt, ans);
        }
        return 0;
    }
  • 相关阅读:
    Oracle Function REGEXP
    Asp.net 注册IIS
    SAP모듈
    C# 程序中,不使用TNS File 中的服务名进行数据库连接
    跟我一起学XNA(2)让物体动起来②(附源码)
    ubuntu显卡的几个帖子
    每秒改变一次背景颜色以及由此引发的一些有趣的小事情(.net方向)
    to myself
    vi编辑器上下左右键盘变成ABCD
    一个最简单的linux hello world模块
  • 原文地址:https://www.cnblogs.com/hzoi-poozhai/p/12681300.html
Copyright © 2020-2023  润新知