题解:CF1929C(Sasha and the Drawing )
一、 理解题意
CF链接
洛谷链接
大佬syz带着 a a a 元来到赌场,赌场的规则如下:
对于每一轮,假设选手下注 y y y 元钱( y y y 应正整数,并且不应当超过他现有的钱数),如果他赢了,就获得 y ⋅ k y\cdot k y⋅k 元,也就是在原基础上增加 y ⋅ ( k − 1 ) y\cdot (k-1) y⋅(k−1) 元;反之,如果他输了,他将不获得任何钱,也就是在原基础上减少 y y y 元。
由于赌场不想被告,这里有一个特殊限制:任何人不会连续输 x x x 轮以上。
现在问你,大佬syz能否通过赌博的方式挣到钱。(挣一块钱他就知足啦!)
二、 分析代价
k k k 和 x x x 都是可遍历的,并且多层遍历同一个变量显然是没有意义的,所以考虑 O ( k ) O(k) O(k) 或者 O ( x ) O(x) O(x) 或者 O ( k x ) O(kx) O(kx) 的算法。
三、 设计算法
首先,大佬syz不能放过任何一次赚钱的机会,也就是说,在每一轮下注时,如果他赢了,他所赚的钱一定能够补回他之前所输掉的钱,并且能够额外赚至少 1 1 1 元钱。也就是说,设他之前输掉了 z z z 元钱,则他这一轮要下注 ⌊ z k − 1 ⌋ + 1 \lfloor\dfrac{z}{k-1}\rfloor+1 ⌊k−1z⌋+1 元钱。
继续思考,显然最差情况下,他要赌到第 x + 1 x+1 x+1 轮他才会赚钱,因此我们就遍历钱 x + 1 x+1 x+1 轮,如果某一轮为止,他需要花出去的钱已经大于 a a a 了,那么他就有可能无法通过赌博赚到钱。
四、 实现代码
#include<bits/stdc++.h>
using namespace std;
int a=0,k=0,t=0,x=0;
int main(){scanf("%d",&t);while(t--){scanf("%d%d%d",&k,&x,&a);long long lost=0;bool flag=false;for(int i=1;i<=x+1;i++){lost+=lost/(k-1)+1;if(lost>a){printf("NO\n");flag=true;break;}}if(flag==false){printf("YES\n");}}return 0;
}