题目的意思很简单,一只乌龟从起始点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; } };