题解:B4050 [GESP202409 五级] 挑战怪物

· · 题解

原题

B4050

题目大意

一个数 h 每次操作有对 h 进行减去 2^{i-1} 减去一个质数,为 0 停止,求操作次数。

解法

step1. 如果 h 是质数,则直接输出 ans (操作次数)。

step2. 如果不是减去 2^{i-1} ,并且 ans\longrightarrow ans+1

step3. 如果 h 小于 0 ,说明不可击败怪物。

step4. 如果 h 等于 0 ,输出 ans

step5.重复步骤。

问题

魔法攻击

题目中说:

至多一次魔法攻击。

众所周知质数均为奇数(这里不讨论 2 ),有两种情况:

但是在程序中,如果 $h$ 已经是质数那么会被魔法攻击变成 $0$ ; $h$ 不是质数,那么**一定**会被 $2^0$ 变为偶数。 $h$ 为偶数,答案为奇数,减完后一定会被 $2^{0}$ 再变为偶数,然后在后面操作中会被物理攻击(减去 $2^{i-1}$ )中变成 $0$。 但是在程序中, $h$ 会被物理攻击(减去 $2^{i-1}$ ),变为 $2$ 或 $0$ 。如果结果 $h$ 为 $2$ ,也会被魔法攻击变成 $0$。 如果 $h$ 为 $2$ ,也会被魔法攻击变成 $0$。 所以只能进行一次魔法攻击(减去质数)。 # 代码 ```cpp #include<iostream> using namespace std; int t; const int maxn=1e5+1; bool prime[maxn]; int main(){ cin>>t; for(int i=2;i<=maxn;i++){//处理质数 prime[i]=true; } for(int i=2;i<=maxn;i++){ if(prime[i]){ for(int j=i*2;j<=maxn;j+=i){ prime[j]=false; } } } for(int i=1;i<=t;i++){ int ans=0; int h; cin>>h; for(int j=1;1;j*=2){//计算ans if(prime[h]){//魔法攻击 ans++; break; } h-=j;//物理攻击 ans++; if(h<0){ ans=-1; break; } if(h==0){ break; } } cout<<ans<<endl; } return 0; } ``` 复杂度:$\Theta \left ( t\log_{2}{h} \right ) $。