CSP-202309-3-梯度求解

CSP-202309-3-梯度求解

  • 作为一个算法小白,本人第一次接触大模拟的题,本题的算法参考自:【CSP】202309-3 梯度求解

解题思路

1.输入处理

  • getchar();:从标准输入读取一个字符。这里它的作用可能是用来“吃掉”(消耗)前一个输入后留下的换行符。确保getline能正确读取到下一行文本。

  • getline(cin, op);:从标准输入流cin中读取一行文本,直到遇到换行符(用户按下回车键),然后将读取到的文本(不包括换行符)存储到之前声明的字符串变量中。

2.逐个处理表达式中的元素

(1)变量 x i x_i xi的表示

struct elem {int index; // 变量索引,即x的下标long long value; // 变量值long long derivative; // 对应变量的导数值
};
  • 注意,这里因为最后求的是导函数的值,而无需记录导数的形式。例如,对于 f ( x ) = x 2 , x = 1 f(x)=x^2,x=1 f(x)=x2,x=1,其导函数 f ′ ( x ) = 2 x f'(x)=2x f(x)=2x,这里我们直接记录 f ′ ( 1 ) = 2 f'(1)=2 f(1)=2,即derivative=2

(2)将数字字符串转换为长整型

long long str2ll(string a) {int sign = 1; // 判断是正数还是负数long long ans = 0;if (a[0] == '-')sign = -1;for (int i = 0; i < a.length(); i++) {if (a[i] != '-')ans = 10 * ans + (a[i] - '0');}return ans * sign;
}

(3)使用 stringstream 逐个处理 op 字符串中的元素

  • std::stringstream 是一个流类,可以像输入/输出流一样操作字符串。允许把字符串分割成多个部分,根据空白字符(如空格、制表符等)来拆分原始字符串。

  • 循环的作用是逐个读取 op 字符串中的每个以空格分隔的子字符串,并在每次迭代中处理这些子字符串。这种处理方式对于解析和执行基于逆波兰表示法(RPN)的算术表达式非常有效,因为它允许程序按照操作的顺序(从左到右)逐步计算表达式的结果。

stringstream ss(op);
string s;
while (ss >> s) {}

(4)逆波兰式的处理逻辑

  • 题目所给的字符串只涉及:x,x的索引,运算符+-*,常数
  • 整理来看可以分为两类:变量+运算符,这也就明确了处理的逻辑。
    • 变量 x i x_i xi,存入elem中。

      if (s[0] == 'x') {elem a;a.index = str2ll(s.substr(1, s.length() - 1)); // 得到变量下标a.derivative = xIndex == a.index ? 1 : 0; // 该变量是否要被求偏导(导数是 1,否则为 0)a.value = value[a.index]; // 变量在给定的值数组中的值st.push(a); // 将包含变量信息的结构体 a 压入栈中,以便后续计算表达式的值和导数(和数字运算一样)
      }
      
    • 运算符,由于求导运算本质上还是算数运算,并且是给定了变量值,本质上还是我们之前遇到过的算数运算的规则:遇到运算符,移出栈顶的两个操作数,进行对应的运算res用于保存运算结果。

      elem op2 = st.top();
      st.pop();
      elem op1 = st.top();
      st.pop();
      elem res;
      
    • 由于求的是导数,这里的+-*不再是普通意义上的+-*,要符合导数运算的规则。

      switch (s[0]) {
      case '+': {res.value = ((op1.value + op2.value) % MOD + MOD) % MOD;res.derivative = ((op1.derivative + op2.derivative) % MOD + MOD) % MOD;break;
      }
      case '-': {res.value = ((op1.value - op2.value) % MOD + MOD) % MOD;res.derivative = ((op1.derivative - op2.derivative) % MOD + MOD) % MOD;break;
      }
      case '*': {res.value = ((op1.value * op2.value) % MOD + MOD) % MOD;res.derivative = ((op1.derivative * op2.value + op1.value * op2.derivative) % MOD + MOD) % MOD;
      }
      }
      st.push(res);
      
    • 常数,类似于非变量的 x i x_i xi

      else {elem a;a.value = str2ll(s);a.derivative = 0;st.push(a);
      }
      
  • 最终,栈顶的结果即为运算结果。

3.完善代码

#include <iostream>
#include <vector>
#include <stack>
#include <sstream>using namespace std;// 定义一个结构体 elem,用于表示表达式中的元素
struct elem {int index; // 变量索引long long value; // 变量值long long derivative; // 对应变量的导数
};const long long MOD = 1000000007; // 模数// 将字符串转换为长整型
long long str2ll(string a) {int sign = 1; // 判断是正数还是负数long long ans = 0;if (a[0] == '-')sign = -1;for (int i = 0; i < a.length(); i++) {if (a[i] != '-')ans = 10 * ans + (a[i] - '0');}return ans * sign;
}int main() {int n, m;cin >> n >> m; // 输入变量个数和表达式数量string op;getchar();getline(cin, op); // 获取表达式字符串vector<elem> expr;stack<elem> st;for (int i = 0; i < m; i++) {int xIndex;vector<long long> value(n + 1);cin >> xIndex; // 输入变量xi,其余均视为常量for (int j = 1; j <= n; j++)cin >> value[j]; // 输入每个变量的值stringstream ss(op);string s;while (ss >> s) {// 判断是否是变量if (s[0] == 'x') {elem a;a.index = str2ll(s.substr(1, s.length() - 1)); // 得到变量的索引a.derivative = xIndex == a.index ? 1 : 0; // 变量对目标变量的导数是 1,否则为 0a.value = value[a.index]; // 变量在给定的值数组中的值st.push(a); // 将包含变量信息的结构体 a 压入栈中,以便后续计算表达式的值和导数}// 检查当前读取到的字符串 s 是否只有一个字符且为加号、减号或乘号。如果是这三个运算符之一,就执行相应的运算逻辑else if (s.length() == 1 && (s[0] == '+' || s[0] == '-' || s[0] == '*')) {// 处理运算符的逻辑elem op2 = st.top();st.pop();elem op1 = st.top();st.pop();elem res;switch (s[0]) {case '+': {res.value = ((op1.value + op2.value) % MOD + MOD) % MOD;res.derivative = ((op1.derivative + op2.derivative) % MOD + MOD) % MOD;break;}case '-': {res.value = ((op1.value - op2.value) % MOD + MOD) % MOD;res.derivative = ((op1.derivative - op2.derivative) % MOD + MOD) % MOD;break;}case '*': {res.value = ((op1.value * op2.value) % MOD + MOD) % MOD;res.derivative = ((op1.derivative * op2.value + op1.value * op2.derivative) % MOD + MOD) % MOD;}}st.push(res);}else {elem a;a.value = str2ll(s);a.derivative = 0;st.push(a);}}long long ans = st.top().derivative;cout << ((ans % MOD) + MOD) % MOD << endl; // 输出结果取模}return 0;
}

请添加图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/696107.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Kafka_04_Topic和日志

Kafka_04_Topic和日志 Topic/PartitionTopicPartition 日志存储存储格式日志清理删除压缩 Topic/Partition Topic/Partition: Kafka中消息管理的基础单位 Topic和Partition并不实际存在(仅逻辑上的概念) 如: Topic和Partition关系 // 每个日志文件可对应多个日志分段, 其还可…

缓存篇—缓存击穿

在很多场景下&#xff0c;我们的业务通常会有几个数据会被频繁地访问&#xff0c;比如秒杀活动&#xff0c;这类被频地访问的数据被称为热点数据。 如果缓存中的某个热点数据过期了&#xff0c;此时大量的请求访问了该热点数据&#xff0c;就无法从缓存中读取&#xff0c;直接…

《UE5_C++多人TPS完整教程》学习笔记22 ——《P23 记录加入的玩家(Couting Incoming Players)》

本文为B站系列教学视频 《UE5_C多人TPS完整教程》 —— 《P23 记录加入的玩家&#xff08;Couting Incoming Players&#xff09;》 的学习笔记&#xff0c;该系列教学视频为 Udemy 课程 《Unreal Engine 5 C Multiplayer Shooter》 的中文字幕翻译版&#xff0c;UP主&#xff…

如何使用Docker部署MongoDB并结合内网穿透实现远程访问本地数据库

文章目录 前言1. 安装Docker2. 使用Docker拉取MongoDB镜像3. 创建并启动MongoDB容器4. 本地连接测试5. 公网远程访问本地MongoDB容器5.1 内网穿透工具安装5.2 创建远程连接公网地址5.3 使用固定TCP地址远程访问 正文开始前给大家推荐个网站&#xff0c;前些天发现了一个巨牛的 …

2024最佳住宅代理IP服务商有哪些?

跨境出海已成为了近几年的最热趋势&#xff0c;大批量的企业开始开拓海外市场&#xff0c;而海外电商领域则是最受欢迎的切入口。新兴的tiktok、Temu&#xff0c;老牌的Amazon、Ebay&#xff0c;热门的Etsy、Mecari等等都是蓝海一片。跨境入门并不难&#xff0c;前期的准备中不…

Spring Boot打war包部署到Tomcat,访问页面404 !!!

水善利万物而不争&#xff0c;处众人之所恶&#xff0c;故几于道&#x1f4a6; 文章目录 Spring Boot打war包部署到Tomcat&#xff0c;访问页面404 &#xff01;&#xff01;&#xff01;解决办法&#xff1a;检查Tomcat版本和Jdk的对应关系&#xff0c;我的Tomcat是6.x&#x…

Sping基础篇----掌握Sping的控制反转/依赖注入的概念【实战案例总结】

作为一名对技术充满热情的学习者&#xff0c;我一直以来都深刻地体会到知识的广度和深度。在这个不断演变的数字时代&#xff0c;我远非专家&#xff0c;而是一位不断追求进步的旅行者。通过这篇博客&#xff0c;我想分享我在某个领域的学习经验&#xff0c;与大家共同探讨、共…

KVM虚拟机的克隆方式

话不多说&#xff0c;直接上操作 首先确定我们要克隆的模板机器&#xff0c;这样可以方便我们后续克隆许多机器 IP获取最好就是dhcp模式&#xff0c;这样克隆出来的机器就不需要自己再去改ip了 确定需要克隆的模板机以后&#xff0c;先关机再执行克隆操作 virsh shutdown ser…

【SiamFC】《Fully-Convolutional Siamese Networks for Object Tracking》

ECCV 2016 Workshops 文章目录 1 Background and Motivation2 Related Work3 Advantages / Contributions4 Method5 Experiments5.1 Datasets and Metrics5.2 The OTB-13 benchmark5.3 The VOT benchmarks5.4 Dataset size 6 Conclusion&#xff08;own&#xff09;/ Future wo…

Android系统启动流程

android的启动流程是从底层开始进行的&#xff0c;具体如下所示&#xff1a; Android是基于Linux内核的系统&#xff0c;Android的启动过程主要分为两个阶段&#xff0c;首先是Linux内核的启动&#xff0c;然后是Android框架的启动。 可以将Andorid系统的启动流程分为以下五个…

【QT 5 +Linux下软件桌面快捷方式+qt生成软件创建桌面图标+学习他人文章+第二篇:编写桌面文件.desktop】

【QT 5 Linux下软件桌面快捷方式qt生成软件创建桌面图标学习他人文章第二篇&#xff1a;编写桌面文件.desktop】 1、前言2、实验环境3、自我学习总结-本篇总结1、新手的疑问&#xff0c;做这件事目的2、了解.desktop3、三个关键目录以及文件编写1、目录&#xff1a;/opt/2、目录…

【鸿蒙 HarmonyOS 4.0】开发工具安装

一、准备开发环境 1.1、安装IDE 鸿蒙应用开发需要使用配套的IDE——HUAWEI DevEco Studio。 DevEco Studio基于IntelliJ IDEA Community&#xff08;IDEA社区版&#xff09;构建&#xff0c;为鸿蒙应用提供了一站式开发环境&#xff0c;集成了开发、运行、调试以及发布应用的…

Stable Diffusion 模型分享:AstrAnime(Astr动画)

本文收录于《AI绘画从入门到精通》专栏&#xff0c;专栏总目录&#xff1a;点这里。 文章目录 模型介绍生成案例案例一案例二案例三案例四案例五 下载地址 模型介绍 AstrAnime 是一个动漫模型&#xff0c;画风色彩鲜明&#xff0c;擅长绘制漂亮的小姐姐。 条目内容类型大模型…

fastjson解析自定义get方法导致空指针问题

背景 为了在日志中把出入参打印出来&#xff0c;以便验证链路和排查问题&#xff0c;在日志中将入参用fastjson格式化成字符串输出&#xff0c;结果遇到了NPE。 问题复现 示例代码 public static void main(String[] args) {OrganizationId orgId new OrganizationId();N…

【Java多线程】分析线程加锁导致的死锁问题以及解决方案

目录 1、线程加锁 2、死锁问题的三种经典场景 2.1、一个线程一把锁 2.2、两个线程两把锁 2.3、N个线程M把锁&#xff08;哲学家就餐问题&#xff09; 3、解决死锁问题 1、线程加锁 其中 locker 可以是任意对象&#xff0c;进入 synchronized 修饰的代码块, 相当于加锁&…

⭐北邮复试刷题LCR 052. 递增顺序搜索树__DFS (力扣119经典题变种挑战)

LCR 052. 递增顺序搜索树 给你一棵二叉搜索树&#xff0c;请 按中序遍历 将其重新排列为一棵递增顺序搜索树&#xff0c;使树中最左边的节点成为树的根节点&#xff0c;并且每个节点没有左子节点&#xff0c;只有一个右子节点。 示例 1&#xff1a; 输入&#xff1a;root [5,…

DataX - 全量数据同步工具

前言 今天是2024-2-21&#xff0c;农历正月十二&#xff0c;相信今天开始是新的阶段&#xff0c;尽管它不是新的周一、某月一日、某年第一天&#xff0c;尽管我是一个很讲究仪式感的人。新年刚过去 12 天&#xff0c;再过 3 天就开学咯&#xff0c;开学之后我的大学时光就进入了…

TypeScript01:安装TypeScript

一、TypeScript 官方网站&#xff1a;https://www.tslang.cn/docs/index.html 练习场&#xff1a;https://www.typescriptlang.org/zh/play 好处&#xff1a; 强类型语言&#xff0c;对JS弱类型的一个良好补充&#xff1b;TS利于大型项目团队合作&#xff0c;可以一定程度…

ChatGPT实战100例 - (17) 用ChatGPT实现音频长度测量和音量调整

文章目录 ChatGPT实战100例 - (17) 用ChatGPT实现音频长度测量和音量调整获取音频长度pydub获取音频长度获取时长精确到秒格式设定 mutagen获取音频长度 调整音量视频音量调整注意事项 ChatGPT实战100例 - (17) 用ChatGPT实现音频长度测量和音量调整 老王媳妇说上次那个pip挺好…

《VitePress 简易速速上手小册》第7章 高级功能与动态内容(2024 最新版)

文章目录 7.1 动态路由与 API 集成7.1.1 基础知识点解析7.1.2 重点案例&#xff1a;技术博客7.1.3 拓展案例 1&#xff1a;电商网站7.1.4 拓展案例 2&#xff1a;事件管理网站 7.2 状态管理与 Vuex 使用7.2.1 基础知识点解析7.2.2 重点案例&#xff1a;用户认证系统7.2.3 拓展案…