AtCoder ABC 126(C ~ E)

本文解析了CDiceandCoin问题,涉及枚举法计算概率,并提供了C++代码示例。接着介绍了EvenRelation的DFS染色算法,解决树上染色问题。最后,通过转化并查集讨论了如何确定最少观测卡牌数以推断所有点数信息。
摘要由CSDN通过智能技术生成

C Dice and Coin(水)

Description:

Solution:

​ 枚举[1, n] 每个需要cnt次才能大于等于k 对答案贡献为(1 / 2) ^ k

Code:

const int N = 105;
double nums[N];
int n, k;

void init()
{
    nums[0] = 1;
    for(int i = 1; i <= N - 5; i ++)
        nums[i] = nums[i - 1] / 2.0;
}

signed main()
{
    init();
    cin >> n >> k;
    double res = 0;
    for(int i = 1; i <= n; i ++)
    {
        int cur = i, cnt = 0;
        while(cur < k)
            cur *= 2, cnt ++;
        res += nums[cnt];
    }
    printf("%.13lf", res / (1.0 * n));
}

D Even Relation(DFS + 染色 + 贪心)

Description:

​ 给定一棵树,对于树的相邻节点,如果间距为奇数不能染同色,若为偶数就可以染同色

​ 请任意给出一种染色方案(黑|| 白)

Solution:

​ 随便从一个地方开始遍历 如果连着是偶数就染同一个颜色,若不是偶数就换

​ a - b 偶 && a - c 偶 那么b - c 是偶

​ a - b 奇 && a - c 偶 那么b - c 是奇

​ a - b 奇 && a - c 奇 那么b - c 是偶

​ 所以得出结论 只需要根到每一个节点的距离的奇偶性来染色

Code:

const int N = 100005;
struct node {
    int e, val;
};
int n;
LL color[N];
vector<node> g[N];

void dfs(int u, LL len)
{
    color[u] = len;
    for(auto x : g[u])
    {
        int j = x.e;
        if(color[j] != -1)    continue;
        dfs(j, len + x.val);
    }
}

signed main()
{
    scanf("%d", &n);
    rep(i, 1, n + 1)
    {
        int u, v, w;
        scanf("%d%d%d", &u, &v, &w);
        g[u].pb({v, w});
        g[v].pb({u, w});
    }
    memset(color, -1, sizeof color);
    dfs(1, 0);

    rep(i, 1, n + 1)
        printf("%d\n", (color[i] & 1) ? 1 : 0);
}

E 1 or 2(转化并查集)

Description:

​ 有一排写着1或2的卡牌(奇偶性),现在给你两组数的a_i + a_j的奇偶性

​ 请问需要最少知道多少张牌的点数 才能推出所有牌的点数

Solution:

​ 对于两数的组合 我只需要知道一个就可以知道另一个

​ 那们我们用并查集来查找有几个集合就行

Code:

const int N = 100005;
int n, m, res;
int x[N], y[N], z[N];
int fa[N];
 
int fd(int x)
{
    if(x != fa[x])  fa[x] = fd(fa[x]);
    return fa[x];
}
 
void _union(int a, int b)
{
    int t1 = fd(a), t2 = fd(b);
    if(t1 != t2)
        fa[t1] = t2;
}
 
int main()
{
    cin >> n >> m;
    rep(i, 1, n + 1)
        fa[i] = i;
    rep(i, 1, m + 1)
    {
        cin >> x[i] >> y[i] >> z[i];
        _union(x[i], y[i]);
    }
 
    rep(i, 1, n + 1)
        if(fa[i] == i)  res ++;
    cout << res;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值