查看原文
其他

金银岛航线

Y叔叔 YuLabSMU 2022-09-20

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

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<int> getXY(std::string line);
std::vector<double> update_position(std::vector<double> position, std::vector<int> xy);

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<int> getXY(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<double> update_position(std::vector<double> position, std::vector<int> xy) {
  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提供。


往期精彩

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存