问题描述
对于平面直角坐标系上的坐标 (x,y),小 P 定义了如下两种操作:
-
拉伸 k 倍:横坐标 x 变为 kx,纵坐标 y 变为 ky;
-
旋转 θ:将坐标 (x,y) 绕坐标原点 (0,0) 逆时针旋转 θ 弧度(0≤θ<2π)。易知旋转后的横坐标为 xcosθ−ysinθ,纵坐标为 xsinθ+ycosθ。
设定好了包含 n 个操作的序列 (t1,t2,⋯,tn) 后,小 P 又定义了如下查询:
i j x y
:坐标 (x,y) 经过操作 ti,⋯,tj(1≤i≤j≤n)后的新坐标。
对于给定的操作序列,试计算 m 个查询的结果。
输入格式
从标准输入读入数据。
输入共 n+m+1 行。
输入的第一行包含空格分隔的两个正整数 n 和 m,分别表示操作和查询个数。
接下来 n 行依次输入 n 个操作,每行包含空格分隔的一个整数(操作类型)和一个实数(k 或 θ),形如 1 k(表示拉伸 k 倍)或 2 θ(表示旋转 θ)。
接下来 m 行依次输入 m 个查询,每行包含空格分隔的四个整数 i、j、x 和 y,含义如前文所述。
输出格式
输出到标准输出中。
输出共 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
Data
样例输出
-1858706.758 -83259.993
-1261428.46 201113.678
-75099.123 -738950.159
-119179.897 -789457.532
114151.88 -366009.892
AC80
#include <bits/stdc++.h>
using namespace std;
//double sin0(double jiaodu){
// double radians = jiaodu * M_PI / 180.0;
// double sinValue = sin(radians);
// return sinValue;
//}
//double cos0(double jiaodu){
// double radians = jiaodu * M_PI / 180.0;
// double sinValue = cos(radians);
// return sinValue;
//}
int main(){
int n,m;
cin>> n>> m;
double dx[n],dy[n];
double x[m],y[m];
double l[m],r[m];
//输入
for(int i=0;i<n;i++){
cin>>dx[i]>>dy[i];
}
for(int i=0;i<m;i++){
cin>>l[i]>>r[i]>>x[i]>>y[i];
}
for(int i=0;i<m;i++){
double lashen=1,xuanzhuan=0;
//进行操作
for(int j=l[i]-1;j<r[i];j++){
if(dx[j]==1){
lashen=lashen*dy[j];
}
else{
xuanzhuan+=dy[j];
// double xx=x[i];
// double yy=y[i];
// x[i]=xx*cos((-1)*dy[j])-yy*sin((-1)*dy[j]);
// y[i]=xx*cos((-1)*dy[j])+yy*sin((-1)*dy[j]);
}
}
x[i]*=lashen;
y[i]*=lashen;
// double xx=x[i];
// double yy=y[i];
// x[i]=x[i]*cos(xuanzhuan)-y[i]*sin(xuanzhuan);
// y[i]=x[i]*cos(xuanzhuan)+y[i]*sin(xuanzhuan);
cout << fixed << setprecision(3) << x[i]*cos(xuanzhuan)-y[i]*sin(xuanzhuan) << " " << x[i]*sin(xuanzhuan)+y[i]*cos(xuanzhuan) << endl;
}
//for(int j=0;j<m;j++) cout << x[j] << " " << y[j] << endl;
// for(int j = 0; j < m; j++) {
// cout << fixed << setprecision(3) << x[j] << " " << y[j] << endl;
// }
return 0;
}
优化一下(还是80)超时了
#include <bits/stdc++.h>
using namespace std;
int main(){
int n,m;
cin>> n>> m;
double dx[n],dy[n];
double x[m],y[m];
double l[m],r[m];
//输入
for(int i=0;i<n;i++){
cin>>dx[i]>>dy[i];
}
for(int i=0;i<m;i++){
cin>>l[i]>>r[i]>>x[i]>>y[i];
double lashen=1,xuanzhuan=0;
for(int j=l[i]-1;j<r[i];j++){
if(dx[j]==1){
lashen=lashen*dy[j];
}
else{
xuanzhuan+=dy[j];
}
}
x[i]*=lashen;
y[i]*=lashen;
cout << fixed << setprecision(3) << x[i]*cos(xuanzhuan)-y[i]*sin(xuanzhuan) << " " << x[i]*sin(xuanzhuan)+y[i]*cos(xuanzhuan) << endl;
}
return 0;
}
AC题解使用了动态数组
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n, m;
cin >> n >> m;
//用vector来使用动态数组
vector<double> a(n+1);
vector<double> b(n+1);
for (int i = 1; i <= n; i++)
{
int x;
cin >> x;
if (x == 1)
{
cin >> a[i];
b[i] = 0;
}
else
{
cin >> b[i];
a[i] = 1;
}
}
vector<double> sum1(n+2), sum2(n+2);
sum1[0] = 1;
sum2[0] = 0;
//直接计算前缀和(根据递推关系式直接求解)
for (int i = 1; i <=n; i++)
{
sum1[i] = a[i] * sum1[i - 1];
sum2[i] = b[i] + sum2[i - 1];
}
//根据所给公式计算m次的结果
for (int i = 0; i < m; i++)
{
int start, end;
double x, y;
cin >> start >> end >> x >> y;
double k = sum1[end] / sum1[start - 1];
double theta = sum2[end] - sum2[start - 1];
x = x * k;
y = y * k;
double temp = x;
x = x * cos(theta) - y * sin(theta);
y = temp * sin(theta) + y * cos(theta);
printf("%.3lf %.3lf\n", x, y);
}
return 0;
}