HDUOJ 6838 Battle for Wosneth

HDUOJ 6838 Battle for Wosneth

题目链接

Problem Description

你在打游戏的时候碰到了如下问题:

有两个人记作Alice和Bob,Bob的生命值为m,Alice的生命值很高,所以可以认为是无限的。两个人的攻击命中率分别为p%,q%。两个人轮流攻击对方。从Alice开始攻击,每次攻击的时候,如果Alice命中,那么能让对方的生命值减低1,同时自己的生命值能恢复1,如果Bob命中,那么能让对方的生命值减低1,注意Bob不会自己回血。

直到Bob的血量变为0,游戏结束。Alice想知道,游戏结束的时候,自己期望生命值变化是多少,对998244353取模。

注意这里的变化量不是绝对值,也就是如果50%的概率加一,50%的概率减一,那么期望的变化量就是0。

对于一个分数a/b,其中gcd(a,b)=1,那么我们认为这个分数对998244353取模的值为一个数c(0≤c<998244353)满足bc≡a(mod998244353)。

Input

第一行一个正整数T(1≤T≤1e4)表示数据组数。

对于每组数据,第一行三个整数m,p,q(1≤m≤1e9,1≤p,q≤100)。

Output

每组测试数据,输出一个数,表示答案。

Sample Input

2
4 100 100
1 50 50

Sample Output

1
499122177

个人是真的讨厌概率题,算得头昏脑胀,关键题解也没说清楚,就说这是一个简单的等比数列求和,我也是一知半解,但是抛开题解我发现可以这么想,把 p p p q q q 当作攻击力,那么 Alice 一定攻击了 m m m 点伤害,也即恢复了 m m m 点血,而 Bob 相当于攻击了 m p − 1 \frac{m}{p}-1 pm1 回合,每回合伤害为 q q q,所以答案就是 m − ( m p − 1 ) ∗ q m-(\frac{m}{p}-1)*q m(pm1)q
AC代码如下:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=998244353;
ll power(ll a,ll b){return b?power(a*a%mod,b/2)*(b%2?a:1)%mod:1;}
int main()
{
    int t;
    scanf("%d",&t);
    ll inv=power(100,mod-2);
    while(t--){
        ll m,p,q;
        scanf("%lld%lld%lld",&m,&p,&q);
        p=p*inv%mod;
        q=q*inv%mod;
        ll ans=m-(m*power(p,mod-2)%mod-1)*q;
        if(ans<0) ans=mod-abs(ans)%mod;
        printf("%lld\n",ans);
    }
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

旺 崽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值