题目的意思很简单,一只乌龟从起始点A开始,执行N条命令,命令有四种,向左、右转一定的角度,向前、后爬行若干距离,问说如何安排着N条命令,使得最后到达的终点B离A最远,给出这个最远的距离。
如果命令只有前进和旋转的话,易知不旋转,直接前进到不能前进是最优的,后退同理。
当有前进和后退同在时,将不在一起的前进的命令都抽取出来从最初的位置开始接起,根据向量相加是不变的,该结果不变,而根据之前提到的,直着连是最优的,所以要直着连,而且直接拿过来的等价情况还可能不能达到(因为包含旋转的角度),但已经不重要了,因为不管如何摆,都没有直着摆要优,同理后退的情况。
所以处理的方法就是将前进和后退分别捡出来,接起来,枚举可能的旋转就好了。
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
#include <cmath>
using namespace std;
typedef stringstream SS;
const double PI = asin(1.0) * 2;
class TurtleSpy {
public:
bool can[55][360];
double maxDistance(vector <string> c) {
double f, b;
vector<int> d;
f = b = 0;
for(int i = 0; i < c.size(); i++) {
SS s(c[i]);
string str;
int deg;
s >> str >> deg;
if(str == "forward") f += deg;
else if(str == "backward") b += deg;
else if(str == "left") d.push_back(deg);
else d.push_back(360 - deg);
}
memset(can, false, sizeof(can));
can[0][0] = true;
int n = d.size();
for(int i = 0; i < n; i++) {
for(int j = 0; j < 360; j++) {
if(can[i][j]) {
can[i + 1][j] = true;
can[i + 1][(j + d[i]) % 360] = true;
}
}
}
double res = 0.0;
for(int i = 0; i < 360; i++) {
if(can[n][i]) {
double angle = i * PI / 180;
res = max(res, sqrt(f * f + b * b - 2 * f * b * cos(angle)));
}
}
return res;
}
};