SRM538 D1 L2

Problem Statement

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

  

原文地址:https://www.cnblogs.com/litstrong/p/2422457.html