试题编号: | 202309-2 |
试题名称: | 坐标变换(其二) |
时间限制: | 2.0s |
内存限制: | 512.0MBqi |
前缀和解法。
旋转和伸缩的顺序不影响结果,只需要确定i~j步之后,总共伸缩的倍数,和旋转的度数,代入公式计算即可。
假设(x,y)经过i~j操作,得到(dx,dy):
总共伸缩的倍数k'为k[i]*k[i+1]*...*k[j] =prek[j]/prek[i-1] ,
总共旋转的度数theta'为theta[i]+theta[i+1]+...+theta[j] =pretheta[j]-pretha[i-1]
dx =[ x* cos(theta')-y* sin(theta') ]*k'
dy =[ x* sin(theta')+y* cos(theta') ]*k'
保留三位小数输出
#include<bits/stdc++.h>
#define PI acos(-1)
using namespace std;
int main()
{
int n,m;
double k[1000000],theta[1000000],prek[1000000],pretheta[1000000];
cin>>n>>m;
prek[0]=1;
pretheta[0]=0;
for(int i=1;i<=n;++i){
int t;
double tmp;
cin>>t>>tmp;
if(t==1){
k[i]=tmp;
theta[i]=0;
}
else{ //t=2
k[i]=1;
theta[i]=tmp;
}
prek[i]=prek[i-1]*k[i]; //伸缩用乘法
pretheta[i]=pretheta[i-1]+theta[i];//旋转角度用加法
}
for(int i=1;i<=m;++i){
int s,t; double x,y,dx,dy;
cin>>s>>t>>x>>y;
//每输入一组数据就输出一组变换后的数据
//为什么是s-1?比如说你需要7~9的变换,就需要经过7,8,9的变换,pre[9]-pre[7]并没有7的变换,所以需要pre[9]-pre[6]。
dx=x*cos(pretheta[t]-pretheta[s-1])-y*sin(pretheta[t]-pretheta[s-1]);
dx*=prek[t]/prek[s-1];
dy=x*sin(pretheta[t]-pretheta[s-1])+y*cos(pretheta[t]-pretheta[s-1]);
dy*=prek[t]/prek[s-1];
printf("%.3lf %.3lf\n",dx,dy);//保留三位小数
}
return 0;
}