寻找胡笳俱乐部
胡笳(HúJiā)是中国古代的一种传统乐器,也称为胡琴。它被认为是二胡的前身,在中国古代音乐中具有重要的地位。胡笳是由马尾和竹子制或的弓弦乐器,外观与二胡相似。
它有两根弦,演奏者使用弓拉动琴弦发出声音。
光明小区的小明从网上了解到胡笳,得知幸福小区有一家胡笳俱乐部,小明想去幸福小区寻找胡笳俱乐部。
幸福小区可以看作一个n*n的矩形,y位置有一个路人,胡笳俱乐部所在的位置是(n,n),小明可以在(1,1)(1.n)(n,1)中任意一个位置开始自己的寻找。
A 路人:小明可以在路人的指引下向上/下/左/右任意一个方向移动一格。
B 路人:小明可以在路人的指引下向上/下/左/右任意一个方向移动两格。
C路人:小明可以在路人的指引下向左上/左下/右上/右下任意一个方向移动一格。
D路人:路人受伤需要小明的帮助,使他不能继续自己的寻找。
小明寻找每个俱乐部需要一天的时间。如果小明不能找到胡笳俱乐部,请告诉他“Go to find Marx",否则请告诉他,他的寻找最少需要多少天?
输入:第一行一个整数 n;
接下来 n行,每行 n个字母(A,B,C,D)表示幸福小区的路人。
输出:第一行一个整数表示最少的天数或者“Go to find Marx”(“引号不要输出”)
一、HuJiaClub.hpp
#ifndef HuJiaClub_hpp
#define HuJiaClub_hpp
#include <stdio.h>
#include <vector>
// 定义位置
struct Position {
int x, y;
};
// 定义寻找方向
enum class Direction {
UP,
DOWN,
LEFT,
RIGHT,
LEFT_UP,
LEFT_DOWN,
RIGHT_UP,
RIGHT_DOWN
};
// 定义路人类型
enum class Stranger {
A,
B,
C,
D
};
class HuJiaClub {
public:
// 构造函数
HuJiaClub(int n, const std::vector<std::vector<Stranger>>& matrix);
int total();
private:
// 幸福小区矩形大小
int size;
/// 定义居民 是个二维矩阵
std::vector<std::vector<Stranger>> matrix;
std::vector<std::vector<bool>> visited;
private:
bool isValidPosition(const Position& pos);
bool canMove(const Position& from, Direction direction, int steps);
/// dfs 是深度优先搜索
int dfs(Position current, Position destination);
int move(Position current, Position destination, Direction direction, int steps);
/// 遍历每个方向探索
int explore(Position current, Position destination, const std::vector<Direction>& directions, int steps);
};
#endif /* HuJiaClub_hpp */
二、HuJiaClub.cpp
#include "HuJiaClub.hpp"
#include "iostream"
// 构造函数
HuJiaClub::HuJiaClub(int n, const std::vector<std::vector<Stranger>>& matrix) : size(n), matrix(matrix) {
visited = std::vector<std::vector<bool>>(size + 1, std::vector<bool>(size + 1, false));
}
int HuJiaClub::total() {
Position start = {1, 1};
Position destination = {size, size};
int days = dfs(start, destination);
if (days == -1) {
return -1;
}
return days + 1;
}
bool HuJiaClub::isValidPosition(const Position& pos) {
return pos.x >= 1 && pos.x <= size && pos.y >= 1 && pos.y <= size;
}
bool HuJiaClub::canMove(const Position& from, Direction direction, int steps) {
Position to = from;
switch (direction) {
case Direction::UP:
to.x -= steps;
break;
case Direction::DOWN:
to.x += steps;
break;
case Direction::LEFT:
to.y -= steps;
break;
case Direction::RIGHT:
to.y += steps;
break;
case Direction::LEFT_UP:
to.x -= steps;
to.y -= steps;
break;
case Direction::LEFT_DOWN:
to.x += steps;
to.y -= steps;
break;
case Direction::RIGHT_UP:
to.x -= steps;
to.y += steps;
break;
case Direction::RIGHT_DOWN:
to.x += steps;
to.y += steps;
break;
}
return isValidPosition(to);
}
int HuJiaClub::dfs(Position current, Position destination) {
if (!isValidPosition(current)) {
return -1;
}
// 如果当前位置是胡笳俱乐部,返回0
if (current.x == destination.x && current.y == destination.y) {
return 0;
}
if (visited[current.x][current.y]) {
return -1;
}
// 标记当前位置已访问
visited[current.x][current.y] = true;
int days = -1;
// 遍历八个方向,并继续深度优先搜索
switch (matrix[current.x - 1][current.y - 1]) {
case Stranger::A: {
std::vector<Direction> directions = {Direction::UP, Direction::DOWN, Direction::LEFT, Direction::RIGHT};
days = explore(current, destination, directions, 1);
}
break;
case Stranger::B: {
std::vector<Direction> directions = {Direction::UP, Direction::DOWN, Direction::LEFT, Direction::RIGHT};
days = explore(current, destination, directions, 2);
}
break;
case Stranger::C: {
std::vector<Direction> directions = {Direction::LEFT_UP, Direction::LEFT_DOWN, Direction::RIGHT_UP, Direction::RIGHT_DOWN};
days = explore(current, destination, directions, 1);
}
break;
case Stranger::D:
break;
}
// 恢复当前位置的访问状态
visited[current.x][current.y] = false;
if (days == -1) {
return -1;
}
return days + 1;
}
int HuJiaClub::explore(Position current, Position destination, const std::vector<Direction> &directions, int steps) {
int days = -1;
for (const auto& direction : directions) {
days = std::max(days, move(current, destination, direction, steps));
}
return days;
}
int HuJiaClub::move(Position current, Position destination, Direction direction, int steps) {
if (canMove(current, direction, steps)) {
int dx = 0, dy = 0;
switch (direction) {
case Direction::UP:
dx = -1;
break;
case Direction::DOWN:
dx = 1;
break;
case Direction::LEFT:
dy = -1;
break;
case Direction::RIGHT:
dy = 1;
break;
case Direction::LEFT_UP:
dx = -1;
dy = -1;
break;
case Direction::LEFT_DOWN:
dx = 1;
dy = -1;
break;
case Direction::RIGHT_UP:
dx = -1;
dy = 1;
break;
case Direction::RIGHT_DOWN:
dx = 1;
dy = 1;
break;
}
Position next = {current.x + steps * dx, current.y + steps * dy};
return dfs(next, destination);
}
return -1;
}
二、main.m调用测试
#include <iostream>
#include <vector>
#include <random>
#include "HuJiaClub.hpp"
using namespace std;
/// 随机创建路人矩阵
std::vector<std::vector<Stranger>> GenerateRandomStranger(int n) {
// 路人矩阵
std::vector<std::vector<Stranger>> randomStrangers(n, std::vector<Stranger>(n, Stranger::A));
// 使用随机设备作为种子
std::random_device rd;
// 使用随机设备生成随机数引擎
std::mt19937 gen(rd());
// 使用均匀分布生成随机枚举值
std::uniform_int_distribution<int> dis(static_cast<int>(Stranger::A), static_cast<int>(Stranger::D));
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
// 生成随机枚举值并赋值给矩阵元素
randomStrangers[i][j] = static_cast<Stranger>(dis(gen));
}
}
return randomStrangers;
}
int main(int argc, const char * argv[]) {
// insert code here...
std::cout << "Please enter an integer:" << std::endl;
int n;
std::cin >> n;
std::vector<std::vector<Stranger>> randomMatrix = GenerateRandomStranger(n);
HuJiaClub hujiaClub(n, randomMatrix);
int result = hujiaClub.total();
if (result == -1) {
std::cout << "Go to find Marx" << std::endl;
} else {
std::cout << "Minimum days needed: " << result << std::endl;
}
return 0;
}