2.坐标变换(其二)
题目大意:给了两个操作让你求Ti-->Tj操作之后的坐标
暴力肯定是不行的80%以上的数据大于1e5我们必须得找办法简化操作,突破点是弧度可以加减的,我们可以这样想逆时针旋转了10弧度,再逆时针转了10弧度相当于逆时针转了20弧度。同样拉伸也是,所以可以看出来操作是可以堆叠在一起的,只需判断区间内的操作即可。可以看作是一个变向的前缀和。为什么想到了前缀和因为最后题目要求查找的是经过区间操作之后的位置我们就可以往前缀和这边想。
//202309-2 坐标变换(其二) 弧度是可以加减的
#include<iostream>
#include<cmath>
using namespace std;
const int N=1e5+10;
struct E
{
int val;
double res;
}e[N];
double s1[N]; //存储累*数组
double s2[N]; //存储弧度数组
int main()
{
s1[0]=1.0;
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>e[i].val>>e[i].res;
if(e[i].val==1)
{
s1[i]=s1[i-1]*e[i].res;
s2[i]=s2[i-1];
}
else
{
s2[i]=s2[i-1]+e[i].res;
s1[i]=s1[i-1];
}
}
while(m--)
{
int k1,k2;
double dx,dy;
cin>>k1>>k2>>dx>>dy;
dx=dx*(s1[k2]/s1[k1-1]);
dy=dy*(s1[k2]/s1[k1-1]);
double dxx=dx,dyy=dy;
double co=cos(s2[k2]-s2[k1-1]),si=sin(s2[k2]-s2[k1-1]);
dx=dxx*co-dyy*si,dy=dxx*si+dyy*co;
printf("%.3lf %.3lf\n",dx,dy);
}
return 0;
}
3.梯度求解
题目大意:题目太复杂了,让我们读取逆波兰式求导,我们骗两个测试点
#include<iostream>
using namespace std;
int main()
{
int n,m;
cin>>n>>m;
if(n>1) return 0;
char c;
int k;
cin>>c>>k;
while(m--)
{
int pos;
int x;
cin>>pos>>x;
if(pos==k) cout<<1<<endl;
else cout<<0<<endl;
}
return 0;
}