挑战 POJ.2991 Crane
2016-07-15 17:14
246 查看
【题意】
有一个为N节的机械手,每次可以让某个关节点旋转到某一角度,问旋转操作结束之后最末端节点的坐标。
【解题方法】
当第i段与第i+1段之间的关节进行旋转时,从第i+1段到第n段都要进行旋转,类似于成段更新(成段旋转),如果把每个线段看成一个向量的话,末端的坐标等于所有向量的和。已知某个点的坐标(x,y),求逆时针旋转
之后的坐标
:
或
【AC code】
//POJ.2991
//Crane
#include <cmath>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn=10010;
struct node{
int l,r;
double x,y;
int lazy;
}Tree[maxn<<2];
int angel[maxn];
//int input[maxn];
void init()
{
for(int i=1; i<=maxn; i++) angel[i]=180.0;
}
void Rotate(int rt,int d)
{
double x,y;
double dd;
dd=(double)d*acos(-1.0)/180.0;
x=Tree[rt].x*cos(dd)-Tree[rt].y*sin(dd);
y=Tree[rt].x*sin(dd)+Tree[rt].y*cos(dd);
Tree[rt].x=x;
Tree[rt].y=y;
}
void PushUp(int rt)
{
Tree[rt].x=Tree[rt<<1].x+Tree[rt<<1|1].x;
Tree[rt].y=Tree[rt<<1].y+Tree[rt<<1|1].y;
}
void PushDown(int rt)
{
if(Tree[rt].lazy)
{
Tree[rt*2].lazy+=Tree[rt].lazy;
Tree[rt*2+1].lazy+=Tree[rt].lazy;
Rotate(rt*2,Tree[rt].lazy);
Rotate(rt*2+1,Tree[rt].lazy);
Tree[rt].lazy=0;
}
}
void Build(int l,int r,int rt)
{
Tree[rt].l=l,Tree[rt].r=r;
Tree[rt].lazy=0;
if(l==r)
{
Tree[rt].x=0;
scanf("%lf",&Tree[rt].y);
return ;
}
int mid=(l+r)/2;
Build(l,mid,rt*2);
Build(mid+1,r,rt*2+1);
PushUp(rt);
}
void update(int L,int R,int val,int rt)
{
if(L<=Tree[rt].l&&Tree[rt].r<=R)
{
Tree[rt].lazy+=val;
Rotate(rt,val);
return ;
}
PushDown(rt);
int mid=(Tree[rt].l+Tree[rt].r)/2;
if(L<=mid) update(L,R,val,rt*2);
if(mid<R) update(L,R,val,rt*2+1);
PushUp(rt);
}
int main()
{
int n,c;
while(~scanf("%d%d",&n,&c))
{
Build(1,n,1);
init();
//puts("success");
int a,b;
for(int i=1; i<=c; i++)
{
scanf("%d%d",&a,&b);
update(a+1,n,b-angel[a],1);
angel[a]=(double)b;
printf("%.2f %.2f\n",Tree[1].x,Tree[1].y);
}
}
}
有一个为N节的机械手,每次可以让某个关节点旋转到某一角度,问旋转操作结束之后最末端节点的坐标。
【解题方法】
当第i段与第i+1段之间的关节进行旋转时,从第i+1段到第n段都要进行旋转,类似于成段更新(成段旋转),如果把每个线段看成一个向量的话,末端的坐标等于所有向量的和。已知某个点的坐标(x,y),求逆时针旋转
之后的坐标
:
或
【AC code】
//POJ.2991
//Crane
#include <cmath>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn=10010;
struct node{
int l,r;
double x,y;
int lazy;
}Tree[maxn<<2];
int angel[maxn];
//int input[maxn];
void init()
{
for(int i=1; i<=maxn; i++) angel[i]=180.0;
}
void Rotate(int rt,int d)
{
double x,y;
double dd;
dd=(double)d*acos(-1.0)/180.0;
x=Tree[rt].x*cos(dd)-Tree[rt].y*sin(dd);
y=Tree[rt].x*sin(dd)+Tree[rt].y*cos(dd);
Tree[rt].x=x;
Tree[rt].y=y;
}
void PushUp(int rt)
{
Tree[rt].x=Tree[rt<<1].x+Tree[rt<<1|1].x;
Tree[rt].y=Tree[rt<<1].y+Tree[rt<<1|1].y;
}
void PushDown(int rt)
{
if(Tree[rt].lazy)
{
Tree[rt*2].lazy+=Tree[rt].lazy;
Tree[rt*2+1].lazy+=Tree[rt].lazy;
Rotate(rt*2,Tree[rt].lazy);
Rotate(rt*2+1,Tree[rt].lazy);
Tree[rt].lazy=0;
}
}
void Build(int l,int r,int rt)
{
Tree[rt].l=l,Tree[rt].r=r;
Tree[rt].lazy=0;
if(l==r)
{
Tree[rt].x=0;
scanf("%lf",&Tree[rt].y);
return ;
}
int mid=(l+r)/2;
Build(l,mid,rt*2);
Build(mid+1,r,rt*2+1);
PushUp(rt);
}
void update(int L,int R,int val,int rt)
{
if(L<=Tree[rt].l&&Tree[rt].r<=R)
{
Tree[rt].lazy+=val;
Rotate(rt,val);
return ;
}
PushDown(rt);
int mid=(Tree[rt].l+Tree[rt].r)/2;
if(L<=mid) update(L,R,val,rt*2);
if(mid<R) update(L,R,val,rt*2+1);
PushUp(rt);
}
int main()
{
int n,c;
while(~scanf("%d%d",&n,&c))
{
Build(1,n,1);
init();
//puts("success");
int a,b;
for(int i=1; i<=c; i++)
{
scanf("%d%d",&a,&b);
update(a+1,n,b-angel[a],1);
angel[a]=(double)b;
printf("%.2f %.2f\n",Tree[1].x,Tree[1].y);
}
}
}
相关文章推荐
- phonegap plugin.xml 示例
- Java 序列化与反序列化 学习手札
- jQuery计算文本宽度和input标签根据输入字符动态自适应宽度的实现
- Salesforce.com Object Query Language (SOQL) 示例
- July 15th 模拟赛C T2 积木游戏 Solution
- Nginx/LVS/HAProxy负载均衡软件的优缺点详解
- iTunes Connect新应用发布流程
- 零散知识点:菜鸟与高手的区别
- 观察者模式在android 上的最佳实践
- 关于 java.io.OptionalDataException
- Objective-C与Swift混编中OC对Swift类视而不见的问题
- 玩转树莓派之八----使用手机作为树莓派的现实屏幕
- java 图片等比压缩
- 利用ps命令查看进程id(部分原创,转载已著名)
- Qt下的模态和非模态对话框
- 延迟加载
- @Transactional注解*
- .net中如何发送HTTP请求网络资源
- JMS学习(七)-ActiveMQ消息的持久存储方式之KahaDB存储
- 随便说下课程设计