CSP认证2023-09:坐标变换(其一)、坐标变换(其二)、梯度求解,python满分代码解答

CSP认证2023-09:坐标变换(其一)、坐标变换(其二)、梯度求解,python满分代码解答

目录

一、坐标变换(其一)

问题描述

输入和输出

思路

代码和结果

c++代码

python代码

二、坐标变换(其二)

问题描述

输入和输出

思路

代码和结果

c++代码

​编辑 python代码

改进 

c++代码

python代码

三、梯度求解

问题描述

输入和输出

思路

代码和结果


一、坐标变换(其一)

问题描述

输入和输出

输入

3 2
10 10
0 0
10 -20
1 -1
0 0

输出 

21 -11
20 -10

思路

定义一个起始原点坐标(0,0),将n个操作依次累加,获得移动后的坐标(x_move,y_move)。接着输入m行坐标(x_res,y_res)时,直接加上移动后的坐标(x_move,y_move)输出结果即可。

代码和结果

c++代码

#include<iostream>
using namespace std;
int main() {int n, m;cin >> n >> m;int move_x = 0;int move_y = 0;for (int i = 0; i < n; i++) {//m行数据int x,y;cin >> x>>y;move_x += x;move_y += y;		}for (int j = 0; j < m; j++) {int input_x, input_y;cin >> input_x >> input_y;cout << input_x + move_x << " " << input_y + move_y << endl;}
}

python代码

n,m=list(map(int,input().split()))
x_move ,y_move= 0,0
for i in range(n):x_1,y_1 = list(map(int,input().split()))x_move+=x_1y_move+=y_1
for j in range(m):x_res, y_res = list(map(int, input().split()))x_res += x_movey_res += y_moveprint(x_res,' ',y_res)

二、坐标变换(其二)

问题描述

输入和输出

输入

10 5
2 0.59
2 4.956
1 0.997
1 1.364
1 1.242
1 0.82
2 2.824
1 0.716
2 0.178
2 4.094
1 6 -953188 -946637
1 9 969538 848081
4 7 -114758 522223
1 9 -535079 601597
8 8 159430 -511187

输出

-1858706.758 -83259.993
-1261428.46 201113.678
-75099.123 -738950.159
-119179.897 -789457.532
114151.88 -366009.892

思路

1、首先将利用两个数组op和value将操作和其对应的值存起来

2、在输入每一个查询时,找到数组op和value的起始位置和终止位置

3、从起始位置和终止位置进行运算即可

代码和结果

这里给出c++代码和python代码

c++代码

#include<iostream>
#include<math.h>
#include<iomanip>
using namespace std;int main(){cout.setf(ios::fixed);cout.precision(3); // 精度为输出小数点后3位int n, m;cin >> n >> m;static int op[100001];static double value[100001];for (int i = 1; i <= n; i++) {int op1;double value1;cin >> op1 >> value1;op[i] = op1;value[i] = value1;}for (int j = 0; j < m; j++) {int op_start, op_end;double value1, value2;cin >> op_start >> op_end >> value1 >> value2;for (int op_index = op_start; op_index <= op_end; op_index++) {//对于第op_index进行以下操作int operation1 = op[op_index];//进行缩放或旋转double v1 = value[op_index];//if (operation1 == 1) {value1 = value1 * v1;value2 = value2 * v1;}else {double value1_copy = value1;value1 = value1 * cos(v1) - value2 * sin(v1);value2 = value1_copy * sin(v1) + value2 * cos(v1);}}cout <<value1 << " " << value2 << endl;}
}

python代码

import mathn,m = list(map(int,input().split()))
op = [0]
value = [0.]
for i in range(1,n+1):operate, v = input().split()op.append(int(operate))value.append(float(v))
for i in range(m):op_start_s,op_end_s,value1_s,value2_s= input().split()op_start = int(op_start_s)op_end = int(op_end_s)value1 = float(value1_s)value2 = float(value2_s)for j in range(op_start,op_end+1):#对于第op_index进行以下操作operation1 = op[j] # 进行缩放或旋转v1 = value[j]if operation1 == 1:value1 = value1 * v1value2 = value2 * v1else:value1_copy = value1 #这一步很重要value1 = value1 * math.cos(v1) - value2 * math.sin(v1)value2 = value1_copy * math.sin(v1) + value2 * math.cos(v1)print(value1,' ',value2)

改进 

然而由于查询过程中存在重复的查询,导致时间复杂度过高而只得到了80分。

通过观察发现,题目让我们求的是给定坐标经过op_start到op_end操作之后的结果,又通过操作内容可知,只包含旋转和坐标缩放这两种操作。从中可以得到以下结论:

首先,这两种操作是不受彼此干扰的;其次,旋转和缩放是可以累积计算的

因此,我们可以通过两个数组记录从1到n个操作的结果,每一步操作是旋转操作和缩放操作的累积。首先计算从op_start到op_end旋转的角度,只需要用op_end旋转的角度减去op_start的角度;其次计算从op_start到op_end缩放的倍数,只需要用op_end缩放的倍数除以op_start缩放的倍数。

c++代码

//存在的问题:考虑到不能每次去遍历操作,因为这样会导致复杂度很高
//解决办法:将操作数组记录下来,因为缩放和旋转是无关的,所以可以使用两个数组存放;旋转是循环的可以实现累加,缩放也是可以累乘的
#include<iostream>
#include<math.h>
#include<iomanip>
using namespace std;
#define pai 3.14159265358979323846
int main() {cout.setf(ios::fixed);cout.precision(3); // 精度为输出小数点后3位int n, m;cin >> n >> m;//static int op_scale[100001];//分开存放两个操作//static int op_xuanzhuan[100001];static double value_scale[100001]={1};static double value_xuanzhuan[100001]={0};//累积缩放值double scale = 1;//累积旋转值,需要mod 2paidouble xuanzhuan = 0;for (int i = 1; i <= n; i++) {//现在存放的就不是第i个操作了,而是前i个操作的累积int op1;double value1;cin >> op1 >> value1;if (op1 == 1) {//同时记录到上一轮的旋转value_xuanzhuan[i] = xuanzhuan;scale = scale * value1;value_scale[i] = scale;}else {//同时记录到上一轮的缩放value_scale[i] = scale;xuanzhuan = xuanzhuan + value1;//先不用取余,最后结果取余就行value_xuanzhuan[i] = xuanzhuan;}}for (int j = 0; j < m; j++) {int op_start, op_end;double value1, value2;cin >> op_start >> op_end >> value1 >> value2;//看op_start的缩放是多少,op_end的缩放系数是多少,除一下就是缩放的系数了double op_scale_start = value_scale[op_start-1];double op_scale_end = value_scale[op_end];double op_xuanzhuan_start = value_xuanzhuan[op_start-1];double op_xuanzhuan_end = value_xuanzhuan[op_end];//首先计算缩放了多少double scale_start_end = op_scale_end / op_scale_start;double xuanzhuan_start_end = fmod((op_xuanzhuan_end - op_xuanzhuan_start), 2 * pai);//op_xuanzhuan_start操作也是进行的double value1_copy = value1;value1 = scale_start_end*(value1 * cos(xuanzhuan_start_end) - value2 * sin(xuanzhuan_start_end));value2 = scale_start_end*(value1_copy * sin(xuanzhuan_start_end) + value2 * cos(xuanzhuan_start_end));cout << value1 << " " << value2 << endl;}return 0;}

python代码

import math
n,m = list(map(int,input().split()))
#累积缩放值
scale = 1
#累积旋转值,需要mod 2pai
xuanzhuan = 0
value_scale = [1]
value_xuanzhuan = [0]
for i in range(1,n+1):#现在存放的就不是第i个操作了,而是前i个操作的累积op1_,value1_ = input().split()op1 = int(op1_)value1 = float(value1_)if op1 == 1:#同时记录到上一轮的旋转value_xuanzhuan.append(xuanzhuan)scale = scale * value1value_scale.append(scale)else:#同时记录到上一轮的缩放value_scale.append(scale)xuanzhuan = xuanzhuan + value1#先不用取余,最后结果取余就行value_xuanzhuan.append(xuanzhuan)
for j in range(m):op_start_s, op_end_s, value1_s, value2_s = input().split()op_start = int(op_start_s)op_end = int(op_end_s)value1 = float(value1_s)value2 = float(value2_s)#看op_start的缩放是多少,op_end的缩放系数是多少,除一下就是缩放的系数了op_scale_start = value_scale[op_start-1]op_scale_end = value_scale[op_end]op_xuanzhuan_start = value_xuanzhuan[op_start-1]op_xuanzhuan_end = value_xuanzhuan[op_end]#首先计算缩放了多少scale_start_end = op_scale_end / op_scale_startxuanzhuan_start_end = (op_xuanzhuan_end - op_xuanzhuan_start)%(2 * math.pi)#op_xuanzhuan_start操作也是进行的value1_copy = value1value1 = scale_start_end*(value1 * math.cos(xuanzhuan_start_end) - value2 * math.sin(xuanzhuan_start_end))value2 = scale_start_end*(value1_copy * math.sin(xuanzhuan_start_end) + value2 * math.cos(xuanzhuan_start_end))print(value1, ' ', value2)

三、梯度求解

问题描述

输入和输出

输入

2 2
x1 x1 x1 * x2 + *
1 2 3
2 3 4

输出

15
3

思路

本题是一道求偏导的题,计算过程很清晰,但是实现起来还是比较麻烦的。接下来简要介绍一下代码的思路:

1、首先,对于每一次输入,将每一个自变量的值存储起来,注:将逆波兰式的多项式使用copy()进行复制,防止后续操作修改了其中的内容。

for _ in range(m):data = list(map(int,input().split()))bianliang_j = data[0]poly_copy_list = poly_list.copy()value_list = data[1:]#从自变量1到自变量n的值bianliang_value_dict = {}#变量值字典for i in range(len(value_list)):if i+1!=int(bianliang_j):x_i = 'x'+str(i+1)bianliang_value_dict[x_i] = str(value_list[i])else:bianliang_j_value = int(value_list[i])

2、将多项式中的不要求偏导的自变量替换成其值,这样就仅包含一个自变量,可以使用字典存储多项式。

#复制多项式,将多项式中的不要求偏导的自变量替换成其值
for i in range(len(poly_copy_list)):if poly_copy_list[i] in bianliang_value_dict.keys():poly_copy_list[i]=bianliang_value_dict[poly_copy_list[i]]
class mul_poly():#对于一个仅包含一个变量的多项式,仅存储其系数和次数即可,但是考虑到稀疏性,得用字典来存储def __int__(self):self.poly = {}#键表示的是多项式的次数,值表示系数

3、开始处理偏导,因为逆波兰式可能只有一项(数值或变量),需要判断一下。如果只有一项,直接用字典形式表示多项式;否则利用栈读取逆波兰式。

  • 在处理逆波兰式时,为了简化运算符的判断,将减法用加法、乘法、系数-1进行表示。
  • 字典形式的多项式的计算方法为: 在乘法中,两重循环多项式a和多项式b的次数项(键),进行次数(键)相加,系数(值)相乘的操作;多项式加法为,单次循环多项式b的次数(键),如果多项式a中没有,则将多项式b的键值对添加到多项式a中;否则将多项式b的系数(值)和多项式a的系数(值)作和,即可完成加法运算。
 if len(poly_copy_list)==1:#只含一个数值或变量temp = trans_mul_poly(poly_copy_list[0]).polyelse:temp = piandao(poly_copy_list)
def piandao(poly):''':param-poly: 列表形式的多项式:return:'''new_poly = []for ele in poly:#a-b = a+ (-1 *)b 减法运算变成加法和乘法if ele=='-':#处理减法运算new_poly.append('-1')new_poly.append('*')new_poly.append('+')else:new_poly.append(ele)poly_stack =[]# #创建一个多项式字典,用以记录多项式加法和乘法的计算结果#通过逆波兰式读取结果for ele in new_poly:if ele not in ['+','*']:#如果不是运算符,则加入poly_stack中poly_stack.append(ele)else:b = poly_stack.pop()a = poly_stack.pop()#a和b初始只可能是 数值(可正可负)、自变量x_1 、之后存在(x_1的多项式)b_mul_poly = trans_mul_poly(b)a_mul_poly = trans_mul_poly(a)#转换成mul_poly对象res = compute(a_mul_poly,b_mul_poly,ele)poly_stack.append(res)result = poly_stack.pop()return result.poly
def compute(a_mul_poly,b_mul_poly,ele):''':param a_mul_poly::param b_mul_poly::param ele: 运算符,取值为"+"或"*":return:'''if ele=='*':res = mul_poly()res.poly = {}#对应位置的系数相乘for a in a_mul_poly.poly.keys():for b in b_mul_poly.poly.keys():# 次数相加,系数相乘a_b_sum_cishu = a+ba_b_sum_xishu = a_mul_poly.poly[a]*b_mul_poly.poly[b]if a_b_sum_cishu not in res.poly.keys():res.poly[a_b_sum_cishu] = a_b_sum_xishuelse:res.poly[a_b_sum_cishu] += a_b_sum_xishureturn reselse:# 对应位置的系数相加for b_cishu in b_mul_poly.poly.keys():if b_cishu not in a_mul_poly.poly.keys():a_mul_poly.poly[b_cishu] = b_mul_poly.poly[b_cishu]else:a_mul_poly.poly[b_cishu] += b_mul_poly.poly[b_cishu]return a_mul_poly

4、获得结果

res = 0
for key in temp.keys():#键为多项式次数,值为系数if key == 0:#常数项求偏导为0continueelif key == 1: #存在0的0次方res+=temp[key]else:res+=key*temp[key]*bianliang_j_value**(key-1)
print(int(res%(10**9+7)))

代码和结果

class mul_poly():#对于一个仅包含一个变量的多项式,仅存储其系数和次数即可,但是考虑到稀疏性,得用字典来存储def __int__(self):self.poly = {}#键表示的是多项式的次数,值表示系数
def compute(a_mul_poly,b_mul_poly,ele):''':param a_mul_poly::param b_mul_poly::param ele: 运算符,取值为"+"或"*":return:'''if ele=='*':res = mul_poly()res.poly = {}#对应位置的系数相乘for a in a_mul_poly.poly.keys():for b in b_mul_poly.poly.keys():# 次数相加,系数相乘a_b_sum_cishu = a+ba_b_sum_xishu = a_mul_poly.poly[a]*b_mul_poly.poly[b]if a_b_sum_cishu not in res.poly.keys():res.poly[a_b_sum_cishu] = a_b_sum_xishuelse:res.poly[a_b_sum_cishu] += a_b_sum_xishureturn reselse:# 对应位置的系数相加for b_cishu in b_mul_poly.poly.keys():if b_cishu not in a_mul_poly.poly.keys():a_mul_poly.poly[b_cishu] = b_mul_poly.poly[b_cishu]else:a_mul_poly.poly[b_cishu] += b_mul_poly.poly[b_cishu]return a_mul_poly
def trans_mul_poly(data):#将数据转成mul_poly对象if isinstance(data,mul_poly):return dataelse:res = mul_poly()res.poly = {}if 'x' in data:#是x自变量res.poly[1] = 1else:#是数值res.poly[0]=int(float(data)%(10**9+7))return resdef piandao(poly):''':param-poly: 列表形式的多项式:return:'''new_poly = []for ele in poly:#a-b = a+ (-1 *)b 减法运算变成加法和乘法if ele=='-':#处理减法运算new_poly.append('-1')new_poly.append('*')new_poly.append('+')else:new_poly.append(ele)poly_stack =[]# #创建一个多项式字典,用以记录多项式加法和乘法的计算结果#通过逆波兰式读取结果for ele in new_poly:if ele not in ['+','*']:#如果不是运算符,则加入poly_stack中poly_stack.append(ele)else:b = poly_stack.pop()a = poly_stack.pop()#a和b初始只可能是 数值(可正可负)、自变量x_1 、之后存在(x_1的多项式)b_mul_poly = trans_mul_poly(b)a_mul_poly = trans_mul_poly(a)#转换成mul_poly对象res = compute(a_mul_poly,b_mul_poly,ele)poly_stack.append(res)result = poly_stack.pop()return result.poly
n,m=list(map(int,input().split()))
poly_list = input().split()
for _ in range(m):data = list(map(int,input().split()))bianliang_j = data[0]poly_copy_list = poly_list.copy()value_list = data[1:]#从自变量1到自变量n的值bianliang_value_dict = {}#变量值字典for i in range(len(value_list)):if i+1!=int(bianliang_j):x_i = 'x'+str(i+1)bianliang_value_dict[x_i] = str(value_list[i])else:bianliang_j_value = int(value_list[i])#复制多项式,将多项式中的不要求偏导的自变量替换成其值for i in range(len(poly_copy_list)):if poly_copy_list[i] in bianliang_value_dict.keys():poly_copy_list[i]=bianliang_value_dict[poly_copy_list[i]]if len(poly_copy_list)==1:#只含一个数值或变量temp = trans_mul_poly(poly_copy_list[0]).polyelse:temp = piandao(poly_copy_list)res = 0for key in temp.keys():#键为多项式次数,值为系数if key == 0:#常数项求偏导为0continueelif key == 1: #存在0的0次方res+=temp[key]else:res+=key*temp[key]*bianliang_j_value**(key-1)print(int(res%(10**9+7)))

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

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

相关文章

辅助驾驶功能开发-外部需求篇-导航式巡航辅助NCA外部依赖及需求

1.功能外部依赖 为了设计满足用户需求的 ICA/NCA 系统,需要用到的系统输入为:环境及驾驶员感知信息、 门锁监测信息、胎压监测信息、驾驶员权限管理、车辆模式管理信息、用户请求输入、转向系统 信息、惯性及导航定位信息、被动安全及约束信息、变速箱系统信息、制动系…

[Java]线程详解

Java线程 一、线程介绍 程序 是为完成特定任务、用某种语言编写的一组指令的集合&#xff08;简单来说就是写的代码&#xff09;。 进程 进程是指运行中的程序&#xff0c;比如我们使用的QQ&#xff0c;就启动了一个进程&#xff0c;操作系统会对该进程分配内存空间。当我…

Swagger在php和java项目中的应用

Swagger在php和java项目中的应用 Swagger简介Swagger在java项目中的应用步骤常用注解 Swagger在php项目中的应用 Swagger简介 Swagger 是一个规范和完整的框架&#xff0c;用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。 总体目标是使客户端和文件系统作为服务器以…

Elasticsearch:ES|QL 查询中的元数据字段及多值字段

在今天的文章里&#xff0c;我来介绍一下 ES|QL 里的元数据字段以及多值字段。我们可以利用这些元数据字段以及多值字段来针对我们的查询进行定制。 ES|QL 源数据字段 ES|QL 可以访问元数据字段。 目前支持的有&#xff1a; _index&#xff1a;文档所属的索引名称。 该字段的…

从0到0.01入门 Webpack| 005.精选 Webpack面试题

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

【C++干货铺】优先队列 | 仿函数

个人主页点击直达&#xff1a;小白不是程序媛 C系列专栏&#xff1a;C干货铺 代码仓库&#xff1a;Gitee 目录 优先队列&#xff08;priority_queue &#xff09;的介绍和使用 priority_queue的介绍 priority_queue的使用 大堆 小堆 priority_queue的模拟实现 仿…

一体化污水处理设备各种材质的优缺点

一体化污水处理设备的材质有多种&#xff0c;包括不锈钢、玻璃钢、聚乙烯塑料、碳钢等。每种材质都有其独特的优点和缺点。 不锈钢材质的优点是防腐性能好&#xff0c;耐磨损&#xff0c;使用寿命长&#xff0c;且外观美观。其缺点是成本较高&#xff0c;不适合在一些特殊的环…

算法-技巧-中等-颜色分类

记录一下算法题的学习12 颜色分类 题目&#xff1a;给定一个包含红色、白色和蓝色、共 n 个元素的数组 nums &#xff0c;原地对它们进行排序&#xff0c;使得相同颜色的元素相邻&#xff0c;并按照红色、白色、蓝色顺序排列。 我们使用整数 0、 1 和 2 分别表示红色、白色和蓝…

堆和栈的区别 重点来说一下堆和栈;堆与栈之间的联系

文章目录 堆和栈的区别重点来说一下堆和栈&#xff1a;那么堆和栈是怎么联系起来的呢? 堆与栈的区别 很明显&#xff1a; 今天来聊一聊java中的堆和栈&#xff0c;工作当中这两个也是经常遇到的&#xff0c;知识我们没有去注意理论上的这些内容&#xff0c;今天就来分享一下。…

Deepin使用记录-deepin系统开启SSH服务

1、检查安装的deepin系统是否已经开启SSH功能。 $ ps -e | grep ssh $ ps -e | grep ssh 查看是否启动ssh 2、安装openssh-server服务 sudo apt-get install openssh-server 如果出现以上提示&#xff0c;就表示你已经安装了ssh服务&#xff0c;只是还没有启动。 3、安装完…

高级驾驶辅助系统 (ADAS)介绍

随着汽车技术持续快速发展,推动更安全、更智能、更高效的驾驶体验一直是汽车创新的前沿。高级驾驶辅助系统( ADAS ) 是这场技术革命的关键参与者,是 指集成到现代车辆中的一组技术和功能,用于增强驾驶员安全、改善驾驶体验并协助完成各种驾驶任务。它使用传感器、摄像头、雷…

C语言,通过数组实现循环队列

实现循环队列最难的地方就在于如何判空和判满&#xff0c;只要解决了这两点循环队列的设计就没有问题。接下来我们将会使用数组来实现循环队列。 接下来&#xff0c;为了模拟实现一个容量为4的循环队列&#xff0c;我们创建一个容量为4 1 的数组。 接下来我们将会对这个数组…