小狗哥哥(洛谷)

本文讨论了一个游戏开发者如何通过给定序列确定游戏中敌对生物死亡所需的武器伤害比例p的数值问题,涉及动态规划和边界条件分析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目

原题

题目背景

luanmenglei 有一个辉煌的现在:他们班的女同学都叫他易酱。

但谁能想到 luanmenglei 有一个悲伤的过去,他五岁的弟弟叫他小狗哥哥。

题目描述

下文的所有参数均默认为整数。

作为一位(7k7k 小游戏的)游戏开发者,你设计了如下(简陋的不如小狗哥哥幼儿园大班的毕业设计的)游戏,存在两个要素:

  1. 一个敌对生物,其血量为 m m m
  2. 主角的武器,分为 n n n 级,第 i i i 级的伤害是 i × p i\times p i×p

游戏的平衡性需要提前规划,所以你还有一个序列 { a n } \{a_n\} {an},其含义如下:

  • a i a_i ai 表示敌对生物被第 i i i 级武器恰好攻击 a i a_i ai 下会死。

可惜你忘记了 p p p 具体是多少,所以你需要求出所有可能的 p p p 的个数。

如果可能有无数个 p p p,那么请输出 xiaogougege

输入格式

第一行两个正整数 n , m n,m n,m

第二行 n n n 个正整数,表示序列 { a n } \{a_n\} {an}

输出格式

一行一个整数,表示可能的 p p p 的个数,或字符串 xiaogougege,其具体含义见题目描述。

样例 #1

样例输入 #1

3 3 3 2 1

样例输出 #1

1

提示

【样例 1 解释】

当武器为 1 1 1 级时,分析可以发现 p p p 要满足 1 ≤ p < 3 2 1 \leq p < \frac{3}{2} 1p<23。 当武器为 2 2 2
级时,分析可以发现 p p p 要满足 3 4 ≤ p < 3 2 \frac{3}{4} \leq p < \frac{3}{2} 43p<23。 当武器为 3 3 3
级时,分析可以发现 p p p 要满足 1 ≤ p 1 \leq p 1p

p p p 是整数。综上,只有当 p = 1 p = 1 p=1 时满足题目所述条件。

【样例 2】

见附加文件中的 game/game2.ingame/game2.out

该样例满足测试点 13 ∼ 20 13\sim 20 1320 的限制。

【数据范围与提示】

对于所有测试数据,保证 1 ≤ n ≤ 1 0 5 1\leq n \leq 10^5 1n105 1 ≤ a i , m ≤ 1 0 9 1\leq a_i,m\leq 10^9 1ai,m109

每个测试点的具体限制见下表:

| 测试点编号 | n ≤ n\leq n | $m,a_i\leq $ | 特殊性质 | | :-: | :-: |:-😐:-😐
| 1 ∼ 9 1\sim 9 19 | 1 0 5 10^5 105 | 1 0 9 10^9 109 | 数据纯随机 | | 10 ∼ 12 10 \sim 12 1012 | 3 3 3
| 5 5 5| 无 | | 13 ∼ 20 13 \sim 20 1320 | 1 0 5 10^5 105 | 1 0 9 10^9 109| 无 |

你需要注意,上文纯随机数据的具体生成程序代码如下:

#include <bits/stdc++.h> using namespace std;

int n, m, w; mt19937
rng(chrono::steady_clock::now().time_since_epoch().count());

int rand(int l, int r) {   assert(l <= r);   return
uniform_int_distribution<>(l, r)(rng); } 

int main() {   scanf("%d%d%d", &n, &m, &w);   printf("%d %d\n", n, m);
for (int i = 1; i <= n; i ++) printf("%d%c", rand(1, w), " \n"[i ==
n]);   return 0; } ```

通俗的说,就是对于给定的 $n,m,w(w\le 10^9)$,数据生成器会随机生成 $n$ 个值域在 $[1,w]$ 内的数,作为
$\{a_n\}$。

思路

这个题目映像里写过类似的。做法是对于目标值建立一个区间,每次数据输入的时候对这个区间进行更新维护。具体来说就是:对于每个输入计算出p的最大值和最小值。假如是第一个攻击,其当前最大值等于 m / ( a 0 − 1 ) m/(a_0-1) m/(a01),当前最小值等于 m / a 0 m/a_0 m/a0。更新最大值和原来最大值和当前最大值里小的哪个(更新最小值与之相反)。最终答案可以取最小值但是无法取最大值。因为如果取最大值,那么此时攻击次数就会等于 a 0 − 1 a_0-1 a01。从理解上来说就是只要当前这个值越接近最大值,那么最后一次攻击时当前怪物的血量就越接近于0.
对于等级的提高只需要对应的将分母乘当前等级,因为当前等级攻击力等于等级数*基础攻击p,最终如果最大值没有被更新还是原始的赋值,说明这里的答案有无限个。这里不用考虑最小值是否会更新,因为最小值一定会更新。这里最大值没更新是如果只有一级的数据且该值恰好等于1,那么计算最大值时分母等于0,导致没有更新最大值

代码

#include<bits/stdc++.h>
using namespace std;
double min(double a,double b){
	return a>b?b:a;
}
double max(double a,double b){
	return a>b?a:b;
}
int main(){
	int m,n,temp;
	double mins=-1,maxs=9999999999;
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>temp;
		mins=max(mins,(double)m/(temp*i)); 
		maxs=min(maxs,(double)m/((temp-1)*i));
	}
	int ans=0; 
	if(maxs==9999999999)
	cout<<"xiaogougege";
	else{
	for(int i = ceil(mins);i<maxs;i++) ans++;  //ceil函数是向上取整
	cout<<ans;}
	
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值