文章目录
-
- @[toc]
-
- 试题编号
- 试题名称
- 时间限制
- 内存限制
- 问题描述
- 输入格式
- 输出格式
- 样例输入
- 样例输出
- 样例说明
- 评测用例规模与约定
- 评分方式
- 提示
- `Python`实现
试题编号
202309-2
试题名称
坐标变换(其二)
时间限制
2.0s
内存限制
512.0MB
问题描述
-
对于平面直角坐标系上的坐标 ( x , y ) (x , y) (x,y),小 P P P定义了如下两种操作
- 拉伸 k k k倍:横坐标 x x x变为 k x kx kx,纵坐标 y y y变为 k y ky ky;
- 旋转 θ \theta θ:将坐标 ( x , y ) (x , y) (x,y)绕坐标原点 ( 0 , 0 ) (0 , 0) (0,0)逆时针旋转 θ \theta θ弧度 ( 0 ≤ θ < 2 π ) (0 \leq \theta < 2 \pi) (0≤θ<2π),易知旋转后的横坐标为 x cos θ − y sin θ x \cos{\theta} - y \sin{\theta} xcosθ−ysinθ,纵坐标为 x sin θ + y cos θ x \sin{\theta} + y \cos{\theta} xsinθ+ycosθ
-
设定好了包含 n n n个操作的序列 ( t 1 , t 2 , ⋯ , t n ) (t_{1} , t_{2} , \cdots , t_{n}) (t1,t2,⋯,tn)后,小 P P P又定义了如下查询
- i j x y i \ j \ x \ y i j x y:坐标 ( x , y ) (x , y) (x,y)经过操作 t i , ⋯ , t j ( 1 ≤ i ≤ j ≤ n ) t_{i} , \cdots , t_{j} (1 \leq i \leq j \leq n) ti,⋯,tj(1≤i≤j≤n)后的新坐标
-
对于给定的操作序列,试计算 m m m个查询的结果
输入格式
- 从标准输入读入数据
- 输入共 n + m + 1 n + m + 1 n+m+1行
- 输入的第一行包含空格分隔的两个正整数 n n n和 m m m,分别表示操作和查询个数
- 接下来 n n n行依次输入 n n n个操作,每行包含空格分隔的一个整数(操作类型)和一个实数( k k k或 θ \theta θ),形如 1 k 1k 1k(表示拉伸 k k k倍)或 2 θ 2 \theta 2θ(表示旋转 θ \theta θ)
- 接下来 m m m行依次输入 m m m个查询,每行包含空格分隔的四个整数 i i i、 j j j、 x x x和 y y y,含义如前文所述
输出格式
- 输出到标准输出中
- 输出共 m m m行,每行包含空格分隔的两个实数,表示对应查询的结果
样例输入
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
样例说明
- 第五个查询仅对输入坐标使用了操作八:拉伸 0.716 0.716 0.716倍
- 横坐标: 159430 × 0.716 = 114151.88 159430 \times 0.716 = 114151.88 159430×0.716=114151.88
- 纵坐标: − 511187 × 0.716 = − 366009.892 -511187 \times 0.716 = -366009.892 −511187×0.716=−366009.892
- 由于具体计算方式不同,程序输出结果可能与真实值有微小差异,样例输出仅保留了三位小数
评测用例规模与约定
- 80 % 80\% 80%的测试数据满足: n , m ≤ 1000 n , m \leq 1000 n,m≤1000
- 全部的测试数据满足
- n , m ≤ 100000 n , m \leq 100000 n,m≤100000
- 输入的坐标均为整数且绝对值不超过 1000000 1000000 1000000
- 单个拉伸操作的系数 k ∈ [ 0.5 , 2 ] k \in [0.5 , 2] k∈[0.5,2]
- 任意操作区间 t i , ⋯ , t j ( 1 ≤ i ≤ j ≤ n ) t_{i} , \cdots , t_{j} (1 \leq i \leq j \leq n) ti,⋯,tj(1≤i≤j≤n)内拉伸系数 k k k的乘积在 [ 0.001 , 1000 ] [0.001 , 1000] [0.001,1000]范围内
评分方式
- 如果你输出的浮点数与参考结果相比,满足绝对误差不大于 0.1 0.1 0.1,则该测试点满分,否则不得分
提示
C/C++
:建议使用double
类型存储浮点数,并使用scanf("%lf", &x);
进行输入,printf("%f", x);
输出,也可以使用cin
和cout
输入输出浮点数;#include
后可使用三角函数cos()
和sin()
Python
:直接使用print(x)
即可输出浮点数x
;from math import cos, sin
后可使用相应三角函数
Java
:建议使用double
类型存储浮点数,可以使用System.out.print(x);
进行输出;可使用Math.cos()
和Math.sin()
调用三角函数
Python
实现
from math import sin, cos, sqrt, atan2
n, m = map(int, input().split())
op = []
for _ in range(n):
num1, num2 = map(float, input().split())
num1 = int(num1)
if num1 == 1:
op.append([num2, 0])
else:
op.append([1, num2])
for i in range(1, n):
op[i][0] *= op[i - 1][0]
op[i][1] += op[i - 1][1]
for _ in range(m):
i, j, x, y = map(int, input().split())
i -= 1
j -= 1
r = sqrt(x * x + y * y)
theta = atan2(y, x)
r *= op[j][0]
theta += op[j][1]
if i:
r /= op[i - 1][0]
theta -= op[i - 1][1]
x = r * cos(theta)
y = r * sin(theta)
print(x, y)