话说海盗拿到金银岛地图,但地图只有起点,以及一行行的航线:

Stand at the pole with the plaque START  
go 140 feet by azimuth 332  
go 460 feet by azimuth 78  
Dig here!

第一行是起点,后面都是go X feet by azimuth Y,其中x是要走的里程数,而y是方向,azimuth 0指向北,azimuth 90指向东。照着指示到了终点就可以挖了。我们的问题就是直接算出终点,直奔终点开挖。

#include <iostream>  
#include <fstream>  
#include <sstream>  
#include <string>  
#include <vector>  
#include <cmath>  
std::vector<intgetXY(std::string line);  
std::vector<doubleupdate_position(std::vector<doublepositionstd::vector<intxy);  
  
int main() {  
  std::ifstream infile("data/id98.txt");  
  std::string line;  
  getline(infile, line);  
  
  while (line != "Stand at the pole with the plaque START") {  
    getline(infile, line);  
  }  
  
  getline(infile, line);  
  std::vector<double> position;  
  position.push_back(0.0);  
  position.push_back(0.0);  
  
  while (line != "Dig here!") {  
    std::vector<int> xy = getXY(line);  
    position = update_position(position, xy);  
    getline(infile, line);  
  }  
  std::cout << rint(position[0]) << " " << rint(position[1]) << std::endl;  
}

主程序一如既往的简单,起点开始的文字忽略,航线开始时,设置位置是原点(0,0),每行读x,y的数值,更新位置,直到读到开挖,就找到最终点了。

std::vector<intgetXY(std::string line) {  
  std::stringstream ss(line);  
  std::string temp;  
  int num;  
  std::vector<int> xy;  
  
  while (getline(ss, temp, ' ')) {  
    if (std::stringstream(temp) >> num) {  
      xy.push_back(num);  
    }  
  }  
  return xy;  
}

读xy数值,一行文字里有数字和单词,首先按空白切割,一个个存入int变量,成功的就是我们要的数字。读取数字之后,我们需要更新位置。

std::vector<doubleupdate_position(std::vector<doublepositionstd::vector<intxy) {  
  std::vector<double> res;  
  int x_direction = 1;  
  if (xy[1> 180) {  
    x_direction = -1;  
  }  
  
  int y_direction = 1;  
  
  if (xy[1> 90 && xy[1< 270) {  
    y_direction = -1;  
  }  
  
  int alpha = xy[1];  
  
  while (alpha > 90) {  
    alpha -= 90;  
  }  
  
  double x = sin(alpha*M_PI/180.0* xy[0];  
  double y = cos(alpha*M_PI/180.0* xy[0];  
  
  if (x_direction * y_direction == -1) {  
    double tmp = x;  
    x = y;  
    y = tmp;  
  }  
  
  x *= x_direction;  
  y *= y_direction;  
  res.push_back(position[0+ x);  
  res.push_back(position[1+ y);  
  return(res);  
}

这里xy[0]是斜边,而xy[1]是角度,所以函数体里面求的就是坐标轴上x和y(相对于上一个状态),所以呢答案就是拿这个x和y来更新上一个状态。这里有个问题是处于不同的象限,第II和IV象限求解的xy要调换,还要考虑取值的正负,正负需要在调换xy之后操作。

其中M_PI是pi变量,rint是round to int。cossin这些函数都由cmath提供。