2022牛客寒假第二场 小沙的炉石(思维)

题目链接:点击这里

题目大意:
初始时,你有 1 1 1 点体力;有 n n n 张攻击牌,每张攻击牌可以消耗 1 1 1 点体力并造成 1 1 1 点基础伤害;有 m m m 张法术牌,每张牌恢复 1 1 1 点体力(体力 无上限);每次使用一张牌后会使之后的攻击牌增加 1 1 1 点伤害,求是否可以使用这些牌恰好造成 k k k 点伤害

题目分析:
我们不妨设 n ≤ m + 1 n\le m+1 nm+1 (若 n > m + 1 n>m+1 n>m+1 时可以看作 n = m + 1 n=m+1 n=m+1 ,因为多余的攻击牌会因缺少体力而无法使用)
我们发现如果采取 攻 击 牌 , 法 术 牌 , 攻 击 牌 , 法 术 牌 . . . . . . 攻击牌,法术牌,攻击牌,法术牌...... ...... 这样的出牌顺序会使造成的伤害最小,造成的伤害为 ∑ i = 1 n 2 i − 1 = n 2 \sum_{i=1}^n2i-1=n^2 i=1n2i1=n2
如果采用 法 术 牌 , 法 术 牌 . . . . . . , 攻 击 牌 , 攻 击 牌 . . . . . . 法术牌,法术牌......,攻击牌,攻击牌...... ............ 这样的出牌顺序会使造成的伤害最大,造成的伤害为 ∑ i = 1 n ( m + i ) = m n + n ( n + 1 ) 2 = n ( 2 m + n + 1 ) 2 \sum_{i=1}^n(m+i)=mn+\frac{n(n+1)}{2}=\frac{n(2m+n+1)}{2} i=1n(m+i)=mn+2n(n+1)=2n(2m+n+1)
我们可以通过法术牌和攻击牌的使用顺序使得伤害值可以取到上下界中的所有值,因此我们可以先算出造成 k k k 点伤害至少需要的牌数 x = k x=\sqrt k x=k ,然后跟 n n n 取一下最小值,然后再看 x x x 能造成的最大伤害是否大于 k k k 即可

具体细节见代码:

//#pragma GCC optimize(2)
//#pragma GCC optimize("Ofast","inline","-ffast-math")
//#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<set>
#include<map>
#include<stack>
#include<queue>
#include<unordered_map>
#define ll long long
#define inf 0x3f3f3f3f
#define Inf 0x3f3f3f3f3f3f3f3f
#define int  ll
#define endl '\n'
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)
using namespace std;
int read()
{
	int res = 0,flag = 1;
	char ch = getchar();
	while(ch<'0' || ch>'9')
	{
		if(ch == '-') flag = -1;
		ch = getchar();
	}
	while(ch>='0' && ch<='9')
	{
		res = (res<<3)+(res<<1)+(ch^48);//res*10+ch-'0';
		ch = getchar();
	}
	return res*flag;
}
const int maxn = 1e6+5;
const int mod = 1e9+7;
const double pi = acos(-1);
const double eps = 1e-8;
int n,m,k;
signed main()
{
	n = read(),m = read();
	n = min(n,m+1);
	int t = read();
	while(t--)
	{
		k = read();
		int x = sqrt(k);
		x = min(x,n);
		if(x*(2*m+x+1)/2 >= k) puts("YES");
		else puts("NO");
	}
	return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值