当前位置: 首页 > news >正文

【蓝桥备赛】技能升级——二分查找

题目链接

技能升级

个人思路

需要给n个技能添加技能点,无论技能点加成如何衰减,每次始终都是选择当前技能加点加成最高的那一项技能,所以最后一次的加点一定也是加在当时技能攻击加成最高的那个。此时,我们去寻找最后一次的加点的攻击力加成的值。
详细思路过程请看Java代码的注释…

参考代码(Java/Cpp)

Java

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;public class Main {static int n;static long m;static long[][] arr;// 快速读入对象,此处不用快读,最后几个数据点过不了,拿不足分数static StreamTokenizer st = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));public static int nextInt() throws IOException {st.nextToken();return (int) st.nval;}public static long nextLong() throws IOException {st.nextToken();return (long) st.nval;}public static void main(String[] args) throws IOException {// 技能数量n = nextInt();// 加点次数,根据数据范围得为 longm = nextLong();// arr[i][0] 为第 i 个 技能初次加点的攻击力加成// arr[i][1] 为第 i 个 技能加点的衰减数arr = new long[n][2];for(int i = 0; i < n; ++i) {arr[i][0] = nextLong();arr[i][1] = nextLong();}// 查找最后一次加点时,所增加的攻击力,采用 左闭右闭区间int left = 0, right = 1000000; // a_i的范围while(left <= right) {int mid = (left + right) / 2;// 如果当前情况可加点次数 ≥ 限制次数 m,则 增大最后一次加点数if (check(mid)) {left = mid + 1;} else {right = mid - 1;}}// cnt 计算当前已经加点的次数, sum 计算当前攻击力long cnt = 0, sum = 0;for(int i = 0; i < n; ++i) {if(arr[i][0] < right) continue;long k = (arr[i][0] - right) / arr[i][1] + 1; // 通过等差数列的形式,计算这个技能衰减能够加点的次数cnt += k;sum += (arr[i][0] + (arr[i][0] - (k - 1) * arr[i][1])) * k / 2; // 等差数列求和}sum += (m - cnt) * right; // 可能会出现最后一次加点的值在多个技能里同时出现,并且该数量超过可以加点的限制次数 m,通过该方法减去多加的技能点System.out.println(sum);}static boolean check(long x) {long num = 0;for(int i = 0; i < n; ++i) {if (arr[i][0] < x) continue;num += (arr[i][0] - x) / arr[i][1] + 1; // 等差数列,求ai变成x需要经过几次,并记上当前ai}return num >= m;}
}

Cpp

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5 + 3;int n;
ll m, a[N], b[N];int check(int x)
{ll cal = 0;for(int i = 0; i < n; ++i){if(a[i] < x) continue;cal += (a[i] - x) / b[i] + 1;}return cal >= m;
}int main()
{ios::sync_with_stdio(0);cin.tie(0);cin >> n >> m;for (int i = 0; i < n; ++i)cin >> a[i] >> b[i];int left = 0, right = 1e6;while(left <= right){int mid = (left + right) / 2;if(check(mid))left = mid + 1;elseright = mid - 1;}ll cnt = 0, res = 0;for(int i = 0; i < n; ++i){if(a[i] < right) continue;int k = (a[i] - right) / b[i] + 1;cnt += k;res += (a[i] * 2 - (k - 1) * b[i]) * k / 2;}res += (m - cnt) * right;cout << res;
}
http://www.lryc.cn/news/272955.html

相关文章:

  • zyqn-arm软中断设置
  • k8s---pod基础下
  • 玩转朋友圈!这样运营朋友圈吸睛又吸金!
  • react学习
  • vue-cli项目中vue.config.js的配置
  • Github 2024-01-04 开源项目日报 Top10
  • 使用GPTs+Actions自动获取第三方数据
  • git提交操作(不包含初始化仓库)
  • 使用YOLOv8和Grad-CAM技术生成图像热图
  • Vue: 多个el-select不能重复选择相同属性
  • 金色麦芒的2023
  • java设计模式学习之【策略模式】
  • Mybatis SQL构建器类 - SqlBuilder and SelectBuilder (已经废弃)
  • 【Linux】不常用命令记录
  • 【docker】安装docker环境并启动容器
  • AIOps探索 | 基于大模型构建高效的运维知识及智能问答平台(2)案例分享
  • 【ESP32接入国产大模型之文心一言】
  • 保湿剂,预计2026年市场规模将达到约230亿美元
  • CodeWhisperer:编码世界中的声音启迪者
  • golang学习专栏
  • el-table表格动态添加列。多组数据拼接和多层级数据的处理
  • ThinkPHP6.0任意文件上传 PHPSESSION 已亲自复现
  • 短说社区运营的使用工具分享(一)
  • 关于.gitignore文件
  • Cell 文章图复现
  • 只需一招彻底解决SOLIDWORKS不显示缩略图预览
  • nccl 源码分析 从 ncclAllReduce 的执行开始认识nccl源代码
  • 仿照AirDrop(隔空投送)优雅地在局域网中传输文件
  • 【PHP】TP5.0及Fastadmin中将查询数据返回对象转为数组
  • 大公司里怎样开发和部署前端代码?