问题描述:
Logo is a programming language built around a turtle. Commands in the language cause the turtle to move. The turtle has a pen attached to it. As the turtle moves, it draw lines on the page. The turtle can be programmed to draw interesting pictures.
We are interested in making the turtle draw a picture, then return to the point that it started from. For example, we could give the turtle the following program:
fd 100 lt 120 fd 100 lt 120 fd 100
The command fd causes the turtle to move forward by the specified number of units. The command lt causes the turtle to turn left by the specified number of degrees. Thus the above commands cause the turtle to draw an equilateral triangle with sides 100 units long. Notice that after executing the commands, the turtle ends up in the same place as it started. The turtle understands two additional commands. The command bk causes the turtle to move backward by the specified number of units. The command rt causes the turtle to turn right by the specified number of degrees.
After executing many commands, the turtle can get lost, far away from its starting position. Your task is to determine the straight-line distance from the turtle's position at the end of its journey back to the position that it started from.
Input
The first line of input contains one integer specifying the number of test cases to follow. Each test case starts with a line containing one integer, the number of commands to follow. The commands follow, one on each line. Each test case will contain no more than 1000 commands.
Output
For each test case, output a line containing a single integer, the distance rounded to the nearest unit.
Sample Input
1 5 fd 100 lt 120 fd 100 lt 120 fd 100Sample Output
0
题目题意:题目给了我们四个操作,fd 原方向前进,lt 向左改变方向,bt 原方向后退,rt 向右改变方向,我们从起点出发,原方向是轴正方向,让我们求经过n次操作后的终点与起点的距离。
题目分析:我们可以用一个矢量表示方向,然后遇到前进或者后退的就可以沿着矢量方向前进或者后退(简单的画图就知道怎么写公式了),遇到改变方向的,我们就可以通过矢量的旋转来改变矢量的方向。
二维矢量旋转公式:点p(x1,y1) 绕点0(x0,y0)旋转r角度d(逆时针)的坐标 (我们可以将绕点定为原点,因为我们只关注它的方向)
X=(x1-x0)*cos(r)-(y1-y0)*sin(r)+x0;
Y=(x1-x0)*sin(r)+(y1-y0)*cos(r)+y0;
顺时针就将r换成-r代码如下;
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
const double PI=acos(-1.0);
struct Point
{
double x,y;
}s,e,v;
double get_dis(Point a,Point b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
int main()
{
int t;
scanf("%d",&t);
while (t--) {
int n,len;
Point cur;
char str[5];
scanf("%d",&n);
cur.x=cur.y=0;
v.x=1,v.y=0;//初始方向
s=cur;
for (int i=1;i<=n;i++) {
scanf("%s%d",str,&len);
if (strcmp(str,"fd")==0) {
cur.x=cur.x+(v.x/sqrt(v.x*v.x+v.y*v.y))*len;
cur.y=cur.y+(v.y/sqrt(v.x*v.x+v.y*v.y))*len;
}
else if (strcmp(str,"bk")==0) {
cur.x=cur.x-(v.x/sqrt(v.x*v.x+v.y*v.y))*len;
cur.y=cur.y-(v.y/sqrt(v.x*v.x+v.y*v.y))*len;
}
else if (strcmp(str,"lt")==0) {
while (len>=360) len-=360;
double r=len/(180.0)*PI;
Point curv=v;
v.x=curv.x*cos(r)-curv.y*sin(r);
v.y=curv.x*sin(r)+curv.y*cos(r);
}
else {
while (len>=360) len-=360;
double r=len/(180.0)*PI;
Point curv=v;
v.x=curv.x*cos(-r)-curv.y*sin(-r);
v.y=curv.x*sin(-r)+curv.y*cos(-r);
}
}
e=cur;
printf("%.0f\n",get_dis(s,e));
}
return 0;
}