标签:map def tac for stack fine 一个 div ring
题意:有n根长度不尽相同的棍子,初始时它们首尾垂直相连,标号为1--n,第一根棍子的下端坐标为(0,0),上端坐标为(0,len[1]),其余棍子依次类推。接下来执行C此旋转,每次输入一个编号num和角度rad,使得第num根棍子和第num+1跟棍子间的逆时针角度变为rad度,求每次旋转后第n跟棍子端点的坐标。
思路:主要是是对此题如何转化为线段树的问题,这是通过对每个结点所在区间进行处理。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <stack>
#include <queue>
#include <map>
#include <algorithm>
#include <vector>
#include <cmath>
#define pi 3.141592653
using namespace std;
const int maxn = 40005;
typedef long long LL;
int N,C;
int L[maxn];
int S[maxn],A[maxn];
double vx[maxn],vy[maxn];
double ang[maxn];
double pre[maxn];
void init(int l,int r,int rt)
{
ang[rt] = vx[rt] = 0.0;
if(r - l == 1) {
vy[rt] = L[l];
}
else{
int lch = rt*2+1;
int rch = rt*2+2;
int mid = (r + l )/2;
init(l,mid,lch);
init(mid,r,rch);
vy[rt] = vy[lch] + vy[rch];
}
}
void change(int s,double a,int rt,int l,int r)
{
if(s <= l) return ;
else if(s < r){
int lch = rt*2+1;
int rch = rt*2+2;
int mid = (l + r)/2;
change(s,a,lch,l,mid);
change(s,a,rch,mid,r);
if(s <= mid) ang[rt] += a;
double t = sin(ang[rt]);
double c = cos(ang[rt]);
vx[rt] = vx[lch] + (c*vx[rch] - t*vy[rch]);
vy[rt] = vy[lch] + (t*vx[rch] + c*vy[rch]);
}
}
void solve()
{
init(0,N,0);
for(int i=1;i<N;i++) pre[i] = pi;
for(int i=0;i<C;i++){
int s = S[i];
double a = A[i]/360.0*2*pi;
change(s,a-pre[s],0,0,N);
pre[s] = a;
printf("%.2f %.2f\n",vx[0],vy[0]);
}
}
int main()
{
while(scanf("%d%d",&N,&C)!=EOF){
for(int i=0;i<N;i++){
scanf("%d",&L[i]);
}
for(int i=0;i<C;i++){
scanf("%d%d",&S[i],&A[i]);
}
solve();
}
return 0;
}
标签:map def tac for stack fine 一个 div ring
原文地址:https://www.cnblogs.com/jaszzz/p/12905912.html